From aecbf876cd0a7894396a2e5034af9d93bf028aa0 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Wed, 13 Mar 2024 15:45:37 +0100 Subject: macOS: Create an app bundle Also enable using `cpack -G DragNDrop` to create a DMG to easily drag Mana into the Applications folder. The DMG is also available as a CI artifact. The minimum deployment target has been set to 10.15, as required due to usage of std::filesystem::create_directories. --- .gitlab-ci.yml | 7 +++++++ CMakeLists.txt | 39 +++++++++++++++++++++-------------- data/CMakeLists.txt | 2 +- src/CMakeLists.txt | 50 +++++++++++++++++++++++++++++++-------------- src/client.cpp | 18 ++-------------- src/main.cpp | 11 ++++++++++ src/utils/specialfolder.cpp | 23 +++++++++++++++++++-- src/utils/specialfolder.h | 5 +++++ 8 files changed, 106 insertions(+), 49 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b2fae39e..10342845 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -49,3 +49,10 @@ macos-build: script: - cmake -G Ninja -B build . - cmake --build build + - cd build + - cpack -G DragNDrop + - mv Mana-*.dmg .. + artifacts: + name: "macos-dmg-$CI_COMMIT_REF_SLUG" + paths: + - Mana-*.dmg diff --git a/CMakeLists.txt b/CMakeLists.txt index f6782168..11b553e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12...3.27) +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") + IF (NOT VERSION) SET(VERSION 0.6.1) ELSE() @@ -32,12 +34,16 @@ OPTION(ENABLE_MANASERV "Enable Manaserv support" ON) OPTION(USE_SYSTEM_GUICHAN "Use system Guichan" ON) IF (WIN32) - SET(PKG_DATADIR ".") - SET(PKG_BINDIR ".") -ELSE (WIN32) - SET(PKG_DATADIR ${CMAKE_INSTALL_DATAROOTDIR}/mana CACHE PATH "Mana datadir") - SET(PKG_BINDIR ${CMAKE_INSTALL_BINDIR}) -ENDIF (WIN32) + SET(CMAKE_INSTALL_DATADIR ".") + SET(CMAKE_INSTALL_LOCALEDIR "translations") + SET(CMAKE_INSTALL_BINDIR ".") +ELSEIF(APPLE) + SET(CMAKE_INSTALL_DATAROOTDIR "Mana.app/Contents") + SET(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}/Resources") + SET(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATADIR}/Translations") +ELSE() + SET(CMAKE_INSTALL_DATADIR ${CMAKE_INSTALL_DATAROOTDIR}/mana) +ENDIF () ADD_SUBDIRECTORY(data) @@ -59,25 +65,28 @@ if(APPLE OR NOT USE_SYSTEM_GUICHAN) ADD_SUBDIRECTORY(libs/guichan EXCLUDE_FROM_ALL) endif() +# Set generic CPack properties here so they may be used in subdirectories +SET(CPACK_PACKAGE_VENDOR "Mana Development Team") +SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") +SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") +SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}") # by default it includes the version +SET(CPACK_PACKAGE_EXECUTABLES "mana;Mana") +SET(CPACK_VERBATIM_VARIABLES TRUE) + ADD_SUBDIRECTORY(src) IF (GETTEXT_FOUND AND ENABLE_NLS) ADD_SUBDIRECTORY(po) ENDIF() -If(UNIX) +If(UNIX AND NOT APPLE) INSTALL(FILES org.manasource.Mana.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) INSTALL(FILES org.manasource.Mana.metainfo.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo) INSTALL(FILES data/icons/mana.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps RENAME org.manasource.Mana.png) INSTALL(FILES data/icons/mana.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps RENAME org.manasource.Mana.svg) ENDIF() -SET(CPACK_PACKAGE_VENDOR "Mana Development Team") -SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") -SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") -SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}") # by default it includes the version -SET(CPACK_PACKAGE_EXECUTABLES "mana;Mana") -SET(CPACK_VERBATIM_VARIABLES TRUE) +# Windows NSIS installer IF(WIN32) SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/data/icons/mana.ico") SET(CPACK_NSIS_INSTALLED_ICON_NAME "mana.exe") @@ -85,7 +94,7 @@ IF(WIN32) SET(CPACK_NSIS_URL_INFO_ABOUT ${PROJECT_HOMEPAGE_URL}) SET(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) SET(CPACK_NSIS_MUI_FINISHPAGE_RUN "mana.exe") - SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ${PKG_BINDIR}) + SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ${CMAKE_INSTALL_BINDIR}) SET(CPACK_NSIS_MANIFEST_DPI_AWARE ON) install(FILES @@ -141,7 +150,7 @@ IF(WIN32) $ENV{MINGW_PREFIX}/bin/libgraphite2.dll $ENV{MINGW_PREFIX}/bin/liblcms2-2.dll $ENV{MINGW_PREFIX}/bin/libpcre2-8-0.dll - DESTINATION ${PKG_BINDIR} + DESTINATION ${CMAKE_INSTALL_BINDIR} ) ENDIF() INCLUDE(CPack) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 56097b6e..198787dc 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -5,5 +5,5 @@ INSTALL(DIRECTORY icons music sfx - DESTINATION ${PKG_DATADIR}/data + DESTINATION ${CMAKE_INSTALL_DATADIR}/data ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72b44ac6..bf0a3e4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,10 +20,10 @@ ENDIF() SET(FLAGS "-DPACKAGE_VERSION=\\\"${VERSION}\\\"") IF (WIN32) - SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${PKG_DATADIR}/\\\"") + SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${CMAKE_INSTALL_DATADIR}/\\\"") SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${CMAKE_INSTALL_LOCALEDIR}/\\\"") -ELSE() - SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${CMAKE_INSTALL_FULL_DATAROOTDIR}/mana/\\\"") +ELSEIF(NOT APPLE) + SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${CMAKE_INSTALL_FULL_DATADIR}/\\\"") SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${CMAKE_INSTALL_FULL_LOCALEDIR}/\\\"") ENDIF() @@ -384,6 +384,8 @@ SET(SRCS utils/physfsrwops.h utils/sha256.cpp utils/sha256.h + utils/specialfolder.cpp + utils/specialfolder.h utils/stringutils.cpp utils/stringutils.h utils/mutex.h @@ -613,20 +615,20 @@ SET(SRCS_MANA IF (WIN32) CONFIGURE_FILE(mana.rc.in mana.rc) - SET(SRCS - ${SRCS} - utils/specialfolder.cpp - utils/specialfolder.h - ${CMAKE_CURRENT_BINARY_DIR}/mana.rc - ) + SET(SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/mana.rc) ENDIF (WIN32) SET (PROGRAMS mana) +set(APP_ICON_NAME "mana.icns") +set(APP_ICON_FILE "${CMAKE_SOURCE_DIR}/data/icons/${APP_ICON_NAME}") +set_source_files_properties(${APP_ICON_FILE} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources") + IF (ENABLE_MANASERV) - ADD_EXECUTABLE(mana WIN32 ${SRCS} ${SRCS_MANA} ${SRCS_TMWA}) + ADD_EXECUTABLE(mana WIN32 ${SRCS} ${SRCS_MANA} ${SRCS_TMWA} ${APP_ICON_FILE}) ELSE(ENABLE_MANASERV) - ADD_EXECUTABLE(mana WIN32 ${SRCS} ${SRCS_TMWA}) + ADD_EXECUTABLE(mana WIN32 ${SRCS} ${SRCS_TMWA} ${APP_ICON_FILE}) ENDIF(ENABLE_MANASERV) TARGET_LINK_LIBRARIES(mana PRIVATE @@ -641,16 +643,34 @@ TARGET_LINK_LIBRARIES(mana PRIVATE ${LIBINTL_LIBRARIES} ${EXTRA_LIBRARIES}) +SET_TARGET_PROPERTIES(mana PROPERTIES + COMPILE_FLAGS "${FLAGS}" + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME} + MACOSX_BUNDLE_GUI_IDENTIFIER org.manasource.Mana + MACOSX_BUNDLE_ICON_FILE ${APP_ICON_NAME} + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_COPYRIGHT "(C) 2004-2024 ${CPACK_PACKAGE_VENDOR}" + MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) + +INSTALL(TARGETS mana + BUNDLE DESTINATION . + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + if(APPLE) target_link_libraries(mana PRIVATE "-framework Foundation") -endif() + SET_TARGET_PROPERTIES(mana PROPERTIES + OUTPUT_NAME Mana) + + set(CPACK_GENERATOR "DRAGNDROP") -INSTALL(TARGETS mana RUNTIME DESTINATION ${PKG_BINDIR}) + install(CODE "include(BundleUtilities) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/Mana.app\" \"\" \"/usr/local/lib\")") +endif() IF (CMAKE_SYSTEM_NAME STREQUAL SunOS) # we expect the SMCgtxt package to be present on Solaris; # the Solaris gettext is not API-compatible to GNU gettext SET_TARGET_PROPERTIES(mana PROPERTIES LINK_FLAGS "-L/usr/local/lib") ENDIF() - -SET_TARGET_PROPERTIES(mana PROPERTIES COMPILE_FLAGS "${FLAGS}") diff --git a/src/client.cpp b/src/client.cpp index 6e12a579..6fe64b2a 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -70,17 +70,13 @@ #include "utils/gettext.h" #include "utils/mkdir.h" +#include "utils/specialfolder.h" #include "utils/stringutils.h" -#ifdef __APPLE__ -#include -#endif - #include #include #ifdef _WIN32 -#include "utils/specialfolder.h" #include #include #endif @@ -264,17 +260,7 @@ Client::Client(const Options &options): } #if defined __APPLE__ - CFBundleRef mainBundle = CFBundleGetMainBundle(); - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); - char path[PATH_MAX]; - if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, - PATH_MAX)) - { - fprintf(stderr, "Can't find Resources directory\n"); - } - CFRelease(resourcesURL); - strncat(path, "/data", PATH_MAX - 1); - mPackageDir = path; + mPackageDir = getResourcesLocation() + "/data"; #else mPackageDir = PKG_DATADIR "data"; #endif diff --git a/src/main.cpp b/src/main.cpp index 68a6b0c3..935f2d89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,10 @@ #include #endif +#ifdef __APPLE__ +#include "utils/specialfolder.h" +#endif + static void printHelp() { using std::endl; @@ -213,7 +217,14 @@ static void initInternationalization() #endif // _WIN32 setlocale(LC_MESSAGES, ""); + +#ifdef __APPLE__ + const auto translationsDir = getResourcesLocation() + "/Translations"; + bindtextdomain("mana", translationsDir.c_str()); +#else bindtextdomain("mana", LOCALEDIR); +#endif + bind_textdomain_codeset("mana", "UTF-8"); textdomain("mana"); #endif // ENABLE_NLS diff --git a/src/utils/specialfolder.cpp b/src/utils/specialfolder.cpp index c351ba1a..c882534d 100644 --- a/src/utils/specialfolder.cpp +++ b/src/utils/specialfolder.cpp @@ -18,8 +18,9 @@ * along with this program. If not, see . */ -#ifdef _WIN32 #include "specialfolder.h" + +#ifdef _WIN32 #include #include @@ -74,4 +75,22 @@ int main() << std::endl; } #endif -#endif +#endif // _WIN32 + +#ifdef __APPLE__ +#include + +std::string getResourcesLocation() +{ + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); + char path[PATH_MAX]; + if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, + PATH_MAX)) + { + fprintf(stderr, "Can't find Resources directory\n"); + } + CFRelease(resourcesURL); + return path; +} +#endif // __APPLE__ diff --git a/src/utils/specialfolder.h b/src/utils/specialfolder.h index 8570d009..36a4e0c1 100644 --- a/src/utils/specialfolder.h +++ b/src/utils/specialfolder.h @@ -27,4 +27,9 @@ std::string getSpecialFolderLocation(const KNOWNFOLDERID &folderId); #endif +#ifdef __APPLE__ +#include +std::string getResourcesLocation(); +#endif + #endif -- cgit v1.2.3-60-g2f50