From 5fbd13465008d021fe43183e7ff40e2bac3a4e65 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Thu, 2 Jan 2025 09:05:29 +0100 Subject: [PATCH] New app layout --- CMakeLists.txt | 131 ++++----- cmake/Bundle.cmake | 77 +++++- cmake/SIPMacros.cmake | 2 +- cmake/VcpkgInstallDeps.cmake | 33 ++- cmake_templates/qgsconfig.h.in | 7 +- images/icons/mac/CMakeLists.txt | 2 +- platform/macos/CPackMacDeployQt.cmake.in | 34 +++ platform/macos/Info.plist.in | 329 +++++++++++++++++++++++ platform/macos/installer_background.png | Bin 0 -> 7061 bytes python/CMakeLists.txt | 2 +- python/PyQt/CMakeLists.txt | 2 +- python/processing/CMakeLists.txt | 2 +- python/testing/CMakeLists.txt | 2 +- src/core/qgsapplication.cpp | 5 +- src/python/qgspythonutilsimpl.cpp | 23 +- 15 files changed, 546 insertions(+), 105 deletions(-) create mode 100644 platform/macos/CPackMacDeployQt.cmake.in create mode 100644 platform/macos/Info.plist.in create mode 100644 platform/macos/installer_background.png diff --git a/CMakeLists.txt b/CMakeLists.txt index c01efd67321..2604850fe0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,10 +43,11 @@ else() endif() if(WITH_VCPKG) + set(TARGET_SYSROOT "${VCPKG_INSTALL_PREFIX}/${VCPKG_TARGET_TRIPLET}") if(WIN32) - list(APPEND CMAKE_PROGRAM_PATH "${VCPKG_INSTALL_PREFIX}/${VCPKG_TARGET_TRIPLET}/tools/python3/Scripts/") + list(APPEND CMAKE_PROGRAM_PATH "${TARGET_SYSROOT}/tools/python3/Scripts/") else() - list(APPEND CMAKE_PROGRAM_PATH "${VCPKG_INSTALL_PREFIX}/${VCPKG_TARGET_TRIPLET}/bin") + list(APPEND CMAKE_PROGRAM_PATH "${TARGET_SYSROOT}/bin") endif() set(PREFER_INTERNAL_LIBS FALSE) else() @@ -884,6 +885,27 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" ST include("cmake/modules/linker.cmake") endif() +set(MIN_PYTHON_VERSION "3.9") +set(Python_FIND_FRAMEWORK "LAST") + +if (WITH_BINDINGS) + find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter Development) +else() + find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter) +endif() + +# Fix python site-packages for Fedora +# See https://github.com/qgis/QGIS/issues/54348#issuecomment-1694216152 +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + if(EXISTS "/etc/fedora-release") + EXECUTE_PROCESS(COMMAND ${Python_EXECUTABLE} -c "import sysconfig;print(sysconfig.get_path(\"platlib\", \"rpm_prefix\"), end=\"\")" OUTPUT_VARIABLE Python_SITEARCH) + endif() +endif() + +message("-- Found Python executable: ${Python_EXECUTABLE} (version ${Python_VERSION})") +message("-- Python library: ${Python_LIBRARIES}") +message("-- Python site-packages: ${Python_SITEARCH}") + ############################################################# # platform specific stuff if (WITH_CORE) @@ -920,61 +942,32 @@ if (WITH_CORE) endif() else() - if (APPLE) - if (POLICY CMP0042) # in CMake 3.0.0+ - set (CMAKE_MACOSX_RPATH OFF) # otherwise ON by default - endif() - if (POLICY CMP0068) # in CMake 3.9.0+ - cmake_policy(SET CMP0068 NEW) - endif() - # for Mac OS X, everything is put inside an application bundle - # save the root install prefix for the app later - set (QGIS_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) - set (QGIS_MACAPP_PREFIX ${CMAKE_INSTALL_PREFIX}/${QGIS_APP_NAME}.app/Contents) - # common prefix for components, let cmake handle it - set (CMAKE_INSTALL_PREFIX ${QGIS_MACAPP_PREFIX}/MacOS) - # 5 bundling levels, each includes previous - # -1 nothing - # 0 fixup the library paths for all QGIS libraries with @loader_path - # 1 Qt frameworks - # 2 non-system libraries, "standard" - # 3 non-system frameworks, "standalone" - set (QGIS_MACAPP_BUNDLE 1 CACHE STRING "What to bundle into app package") - set (QGIS_MACAPP_BUNDLE_USER "" CACHE STRING "Path to user bundling script") - set (QGIS_MACAPP_INSTALL_DEV FALSE CACHE BOOL "Install developer frameworks") - set (QGIS_MACAPP_DEV_PREFIX "/Library/Frameworks" CACHE STRING "Path to install developer frameworks") + if(APPLE) + set(QGIS_MAC_BUNDLE TRUE CACHE BOOL "Install into a mac bundle") + endif() - set (DEFAULT_BIN_SUBDIR bin) - set (QGIS_BIN_SUBDIR_REV ..) - set (DEFAULT_CGIBIN_SUBDIR fcgi-bin) - set (QGIS_CGIBIN_SUBDIR_REV ..) - set (DEFAULT_LIB_SUBDIR lib) - set (QGIS_LIB_SUBDIR_REV ..) - set (QGIS_FW_SUBDIR ../Frameworks) - set (QGIS_FW_SUBDIR_REV ../MacOS) - set (DEFAULT_DATA_SUBDIR ../Resources) - set (QGIS_DATA_SUBDIR_REV ../MacOS) - set (DEFAULT_LIBEXEC_SUBDIR lib/qgis) - set (QGIS_LIBEXEC_SUBDIR_REV ../..) - set (DEFAULT_PLUGIN_SUBDIR ../PlugIns/qgis) - set (QGIS_PLUGIN_SUBDIR_REV ../../MacOS) - set (DEFAULT_INCLUDE_SUBDIR include/qgis) - set (DEFAULT_QML_SUBDIR qml) + if (APPLE AND QGIS_MAC_BUNDLE) + set(CMAKE_MACOSX_RPATH ON) # If this is off, the path will be stripped (completely) at install time, we want to preserve the `@rpath` prefix + set(CMAKE_SKIP_INSTALL_RPATH TRUE) - # Set server moodules path to DEFAULT_LIBEXEC_SUBDIR+'/server' - set (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server) + set(CMAKE_INSTALL_PREFIX "${QGIS_APP_NAME}.app") - # path for framework references when running from build directory - # changed later to reference in-app resources upon install - set (CMAKE_INSTALL_NAME_DIR ${CMAKE_BINARY_DIR}/output/lib) - # recent cmakes force SDKs, recent SDKs don't have user symlinks - # need to find non-system frameworks - # cmake bug #0007250 - CMAKE_SHARED_LINKER_FLAGS ignored when creating - # a framework, so these need to be manually handled with LINK_FLAGS options - set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -F/Library/Frameworks") - set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -F/Library/Frameworks") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -F/Library/Frameworks") + set(APP_CONTENTS_DIR "Contents") + set(APP_MACOS_DIR "${APP_CONTENTS_DIR}/MacOS") + set(APP_FRAMEWORKS_DIR "${APP_CONTENTS_DIR}/Frameworks") + set(APP_RESOURCES_DIR "${APP_CONTENTS_DIR}/Resources") + set(APP_PLUGINS_DIR "${APP_CONTENTS_DIR}/PlugIns") + cmake_path(RELATIVE_PATH Python_SITEARCH BASE_DIRECTORY "${TARGET_SYSROOT}" OUTPUT_VARIABLE _RELATIVE_SITEARCH) + + set(DEFAULT_BIN_SUBDIR ${APP_MACOS_DIR}) + set(DEFAULT_LIB_SUBDIR ${APP_FRAMEWORKS_DIR}) + set(DEFAULT_DATA_SUBDIR ${APP_RESOURCES_DIR}/qgis) + set(DEFAULT_LIBEXEC_SUBDIR ${APP_MACOS_DIR}) + set(DEFAULT_PLUGIN_SUBDIR ${APP_PLUGINS_DIR}/qgis) + set(DEFAULT_INCLUDE_SUBDIR include/qgis) + set(DEFAULT_QML_SUBDIR ${APP_RESOURCES_DIR}/qgis/qml) + set(DEFAULT_PYTHON_SUBDIR ${APP_FRAMEWORKS_DIR}/${_RELATIVE_SITEARCH}) else() # UNIX set (DEFAULT_BIN_SUBDIR bin) @@ -1086,28 +1079,6 @@ option(ENABLE_UNITY_BUILDS "Enable Unity builds, that is compiling several .cpp ############################################################# # Python -set(MIN_PYTHON_VERSION "3.9") -set(Python_FIND_FRAMEWORK "LAST") - - -if (WITH_BINDINGS) - find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter Development) -else() - find_package(Python ${MIN_PYTHON_VERSION} REQUIRED COMPONENTS Interpreter) -endif() - -# Fix python site-packages for Fedora -# See https://github.com/qgis/QGIS/issues/54348#issuecomment-1694216152 -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - if(EXISTS "/etc/fedora-release") - EXECUTE_PROCESS(COMMAND ${Python_EXECUTABLE} -c "import sysconfig;print(sysconfig.get_path(\"platlib\", \"rpm_prefix\"), end=\"\")" OUTPUT_VARIABLE Python_SITEARCH) - endif() -endif() - -message("-- Found Python executable: ${Python_EXECUTABLE} (version ${Python_VERSION})") -message("-- Python library: ${Python_LIBRARIES}") -message("-- Python site-packages: ${Python_SITEARCH}") - if (WITH_CORE AND WITH_BINDINGS) set(PYTHON_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/python) set (QGIS_PYTHON_OUTPUT_DIRECTORY ${PYTHON_OUTPUT_DIRECTORY}/qgis) @@ -1140,8 +1111,12 @@ if (WITH_CORE AND WITH_BINDINGS) set(SIP_INCLUDES ${PYQT_SIP_DIR} ${CMAKE_SOURCE_DIR}/python) set(SIP_CONCAT_PARTS 25) - if (NOT BINDINGS_GLOBAL_INSTALL) - set(Python_SITEARCH ${QGIS_DATA_DIR}/python) + if(BINDINGS_GLOBAL_INSTALL) + set(QGIS_PYTHON_INSTALL_DIR ${Python_SITEARCH}) + elseif(DEFINED DEFAULT_PYTHON_SUBDIR) + set(QGIS_PYTHON_INSTALL_DIR ${DEFAULT_PYTHON_SUBDIR}) + else() + set(QGIS_PYTHON_INSTALL_DIR ${QGIS_DATA_DIR}/python) endif() if (WITH_CUSTOM_WIDGETS) @@ -1238,8 +1213,8 @@ endif() ############################################################# # Enable packaging if (WITH_CORE) - include(Bundle) include(VcpkgInstallDeps) + include(Bundle) endif() if (UNIX AND NOT APPLE) diff --git a/cmake/Bundle.cmake b/cmake/Bundle.cmake index a1ffffd26f4..3036f11cc30 100644 --- a/cmake/Bundle.cmake +++ b/cmake/Bundle.cmake @@ -2,9 +2,9 @@ set(CPACK_GENERATOR) set(CPACK_OUTPUT_CONFIG_FILE "${CMAKE_BINARY_DIR}/BundleConfig.cmake") add_custom_target(bundle - COMMAND ${CMAKE_CPACK_COMMAND} "--config" "${CMAKE_BINARY_DIR}/BundleConfig.cmake" + COMMAND ${CMAKE_CPACK_COMMAND} "--config" "${CMAKE_BINARY_DIR}/BundleConfig.cmake" "--verbose" COMMENT "Running CPACK. Please wait..." - DEPENDS qgis) + DEPENDS "${QGIS_APP_NAME}") if(WIN32 AND NOT UNIX) set (CREATE_NSIS FALSE CACHE BOOL "Create an installer using NSIS") @@ -22,7 +22,6 @@ endif() set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "QGIS") set(CPACK_PACKAGE_VENDOR "Open Source Geospatial Foundation") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") set(CPACK_PACKAGE_INSTALL_DIRECTORY "QGIS ${COMPLETE_VERSION}") set(CPACK_PACKAGE_EXECUTABLES "qgis" "QGIS") @@ -44,4 +43,76 @@ if(CREATE_ZIP) list(APPEND CPACK_GENERATOR "ZIP") endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND QGIS_MAC_BUNDLE) + # TODO HINT relative to VCPKG_HOST_DIR + find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "../../macdeployqt-standalone/build/bin/" NO_DEFAULT_PATH) + + configure_file("${CMAKE_SOURCE_DIR}/platform/macos/Info.plist.in" "${CMAKE_BINARY_DIR}/platform//macos/Info.plist" @ONLY) + install(FILES "${CMAKE_BINARY_DIR}/platform//macos/Info.plist" DESTINATION "${APP_CONTENTS_DIR}") + + set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") + set(CPACK_DMG_FORMAT "UDBZ") + list(APPEND CPACK_GENERATOR "External") + message(STATUS " + macdeployqt/DMG YES ") + configure_file(${CMAKE_SOURCE_DIR}/platform/macos/CPackMacDeployQt.cmake.in "${CMAKE_BINARY_DIR}/CPackExternal.cmake" @ONLY) + set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/CPackExternal.cmake") + set(CPACK_EXTERNAL_ENABLE_STAGING ON) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + +# install(CODE " +# execute_process( +# COMMAND install_name_tool -add_rpath @executable_path/../Frameworks \"${APP_CONTENTS_DIR}/MacOS/QGIS\" +# WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}\" +# RESULT_VARIABLE result +# ) +# if(NOT result EQUAL 0) +# message(FATAL_ERROR \"install_name_tool failed with error code: ${result}\") +# endif() +# ") +endif() +# +# +# +# +# if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") +# set(CPACK_GENERATOR "Bundle") +# set(CPACK_PACKAGE_FILE_NAME "${QGIS_APP_NAME}") +# # DragNDrop +# set(CPACK_DMG_FORMAT "ULFO") +# # set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/packaging/osx/background.tiff") +# # Bundle +# set(CPACK_BUNDLE_NAME "${QGIS_APP_NAME}") +# configure_file("${CMAKE_SOURCE_DIR}/macos/app.info.plist.in" "${CMAKE_BINARY_DIR}/mac/Info.plist") +# set(CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/mac/Info.plist") +# set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/images/icons/mac/qgis.icns") +# +# if(WITH_DESKTOP) +# install(PROGRAMS $ DESTINATION .) +# endif() +# install(FILES ${CPACK_BUNDLE_PLIST} DESTINATION .) +# + + +# set(VCPKG_BASE_DIR "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") + + # install(CODE " + # include(BundleUtilities) + # set(BU_CHMOD_BUNDLE_ITEMS ON) + # set(QT_PLUGIN_IN_BUNDLE \"\") + # message(WARNING \"Fixing plugins\") + # foreach(f ${QT_PLUGIN}) + # message(WARNING \"Fixing ${f}\") + # get_filename_component(QT_PLUGIN_ABSOLUTE \"\${CMAKE_INSTALL_PREFIX}/\${f}\" ABSOLUTE) + # list(APPEND QT_PLUGIN_IN_BUNDLE \"\${QT_PLUGIN_ABSOLUTE}\") + # endforeach(f) + # get_filename_component(BUNDLE_PATH \"\${CMAKE_INSTALL_PREFIX}\" ABSOLUTE) + # fixup_bundle(\"\${BUNDLE_PATH}/${APP_BUNDLE_DIR}\" \"\" \"${VCPKG_BASE_DIR}/lib;\${BUNDLE_PATH}/${APP_BUNDLE_DIR}/Contents/Frameworks\") + # ") +# endif() + +# set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/_CPack_Packages") + include(CPack) diff --git a/cmake/SIPMacros.cmake b/cmake/SIPMacros.cmake index e69e208b6a1..1870a64bd74 100644 --- a/cmake/SIPMacros.cmake +++ b/cmake/SIPMacros.cmake @@ -204,5 +204,5 @@ MACRO(BUILD_SIP_PYTHON_MODULE MODULE_NAME SIP_FILES EXTRA_OBJECTS) ) ENDIF(WIN32) - INSTALL(TARGETS ${_logical_name} DESTINATION "${Python_SITEARCH}/${_parent_module_path}") + INSTALL(TARGETS ${_logical_name} DESTINATION "${QGIS_PYTHON_INSTALL_DIR}/${_parent_module_path}") ENDMACRO(BUILD_SIP_PYTHON_MODULE MODULE_NAME SIP_FILES EXTRA_OBJECTS) diff --git a/cmake/VcpkgInstallDeps.cmake b/cmake/VcpkgInstallDeps.cmake index 2ff89201075..6c142cd889e 100644 --- a/cmake/VcpkgInstallDeps.cmake +++ b/cmake/VcpkgInstallDeps.cmake @@ -5,12 +5,15 @@ endif() set(VCPKG_BASE_DIR "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") if(MSVC) - # At least python3.dll, qgis_analysis.dll and gsl.dll are missing - # Copy everything file(GLOB ALL_LIBS "${VCPKG_BASE_DIR}/bin/*.dll" ) install(FILES ${ALL_LIBS} DESTINATION "bin") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + file(GLOB ALL_LIBS + "${VCPKG_BASE_DIR}/bin/*.dylib" + ) + install(FILES ${ALL_LIBS} DESTINATION "${QGIS_LIB_SUBDIR}") endif() set(PROJ_DATA_PATH "${VCPKG_BASE_DIR}/share/proj") @@ -19,12 +22,22 @@ if(NOT EXISTS "${PROJ_DATA_PATH}/proj.db") message(FATAL_ERROR "proj.db not found at ${PROJ_DATA_PATH}/proj.db") endif() -install(DIRECTORY "${PROJ_DATA_PATH}/" DESTINATION "${CMAKE_INSTALL_DATADIR}/proj") -install(DIRECTORY "${VCPKG_BASE_DIR}/share/gdal/" DESTINATION "${CMAKE_INSTALL_DATADIR}/gdal") -install(DIRECTORY "${VCPKG_BASE_DIR}/bin/Qca/" DESTINATION "bin/Qca") # QCA plugins -install(DIRECTORY "${VCPKG_BASE_DIR}/Qt6/" DESTINATION "bin/Qt6") # qt plugins (qml and others) -if(WITH_BINDINGS) - install(DIRECTORY "${VCPKG_BASE_DIR}/tools/python3/" - DESTINATION "bin" - PATTERN "*.sip" EXCLUDE) +install(DIRECTORY "${PROJ_DATA_PATH}/" DESTINATION "${QGIS_DATA_SUBDIR}/proj") +install(DIRECTORY "${VCPKG_BASE_DIR}/share/gdal/" DESTINATION "${QGIS_DATA_SUBDIR}/gdal") +install(DIRECTORY "${VCPKG_BASE_DIR}/bin/Qca/" DESTINATION "${QGIS_LIB_SUBDIR}/Qca") # QCA plugins +if(MSVC) + install(DIRECTORY "${VCPKG_BASE_DIR}/Qt6/" DESTINATION "${QGIS_LIB_SUBDIR}/Qt6") # qt plugins (qml and others) +else() + install(DIRECTORY "${VCPKG_BASE_DIR}/Qt6/" DESTINATION "${APP_PLUGINS_DIR}/") # qt plugins (qml and others) +endif() +if(WITH_BINDINGS) + # TODO: validate on windows + if(MSVC) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + cmake_path(GET Python_SITEARCH PARENT_PATH _PYTHON_DIR) + + install(DIRECTORY "${_PYTHON_DIR}" + DESTINATION "${APP_FRAMEWORKS_DIR}/lib" + PATTERN "*.sip" EXCLUDE) + endif() endif() diff --git a/cmake_templates/qgsconfig.h.in b/cmake_templates/qgsconfig.h.in index b8f0949c985..ab9ac0d682e 100644 --- a/cmake_templates/qgsconfig.h.in +++ b/cmake_templates/qgsconfig.h.in @@ -37,11 +37,6 @@ #define QSCINTILLA_VERSION_STR "${QSCINTILLA_VERSION_STR}" #endif -#if defined( __APPLE__ ) -//used by Mac to find system or bundle resources relative to amount of bundling -#define QGIS_MACAPP_BUNDLE ${QGIS_MACAPP_BUNDLE} -#endif - #define PYTHON_VERSION "${Python_VERSION}" #define PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}" #define PYTHON_VERSION_MINOR "${Python_VERSION_MINOR}" @@ -51,6 +46,8 @@ #define PROJ_VERSION_MINOR ${PROJ_VERSION_MINOR} #define PROJ_VERSION_PATCH ${PROJ_VERSION_PATCH} +#cmakedefine QGIS_MAC_BUNDLE + #cmakedefine USING_NMAKE #cmakedefine USING_NINJA diff --git a/images/icons/mac/CMakeLists.txt b/images/icons/mac/CMakeLists.txt index b2f9c905f20..89b80eab585 100644 --- a/images/icons/mac/CMakeLists.txt +++ b/images/icons/mac/CMakeLists.txt @@ -2,5 +2,5 @@ if (WITH_DESKTOP) file (GLOB ICONS *.icns) install (FILES ${ICONS} - DESTINATION ${CMAKE_INSTALL_PREFIX}/../Resources) + DESTINATION ${APP_RESOURCES_DIR}) endif() diff --git a/platform/macos/CPackMacDeployQt.cmake.in b/platform/macos/CPackMacDeployQt.cmake.in new file mode 100644 index 00000000000..7d14d66c3da --- /dev/null +++ b/platform/macos/CPackMacDeployQt.cmake.in @@ -0,0 +1,34 @@ +execute_process(COMMAND install_name_tool -add_rpath @loader_path/../Frameworks ${CPACK_TEMPORARY_DIRECTORY}/@QGIS_APP_NAME@.app/Contents/MacOS/QGIS + WORKING_DIRECTORY @CMAKE_BINARY_DIR@ + COMMAND_ERROR_IS_FATAL ANY + ) + +if(NOT "$ENV{MACOS_CODE_SIGN_IDENTITY}" STREQUAL "") + # -appstore-compliant will strip away odbc, psql and webengine plugins + execute_process(COMMAND "@MACDEPLOYQT_EXECUTABLE@" @QGIS_APP_NAME@.app -codesign=${MACOS_CODE_SIGN_IDENTITY} -sign-for-notarization=${MACOS_CODE_SIGN_IDENTITY} + WORKING_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY} + COMMAND_ERROR_IS_FATAL ANY + ) + + execute_process(COMMAND create-dmg --volname "@QGIS_APP_NAME@ Installer" --hide-extension @QGIS_APP_NAME@.app --volicon "@CMAKE_SOURCE_DIR@/images/icons/mac/qgis.icns" --background "@CMAKE_SOURCE_DIR@/platform/macos/installer_background.png" --window-pos 200 120 --window-size 512 320 --icon-size 100 --icon "@QGIS_APP_NAME@.app" 130 160 --app-drop-link 400 155 --codesign "${MACOS_CODE_SIGN_IDENTITY}" @CMAKE_BINARY_DIR@/@QGIS_APP_NAME@-Installer.dmg ${CPACK_TEMPORARY_DIRECTORY}/@QGIS_APP_NAME@.app + RESULT_VARIABLE CREATE_DMG_FAILURE) + + if(CREATE_DMG_FAILURE) + message(STATUS "Creating dmg failed. Retrying ...") + execute_process(COMMAND create-dmg --volname "@QGIS_APP_NAME@ Installer" --hide-extension @QGIS_APP_NAME@.app --volicon "@CMAKE_SOURCE_DIR@/images/icons/mac/qgis.icns" --background "@CMAKE_SOURCE_DIR@/platform/macos/installer_background.png" --window-pos 200 120 --window-size 512 320 --icon-size 100 --icon "@QGIS_APP_NAME@.app" 130 160 --app-drop-link 400 155 --codesign "${MACOS_CODE_SIGN_IDENTITY}" @CMAKE_BINARY_DIR@/@QGIS_APP_NAME@-Installer.dmg ${CPACK_TEMPORARY_DIRECTORY}/@QGIS_APP_NAME@.app + COMMAND_ERROR_IS_FATAL ANY) + endif() +else() + # -appstore-compliant will strip away odbc, psql and webengine plugins + execute_process(COMMAND "@MACDEPLOYQT_EXECUTABLE@" "@QGIS_APP_NAME@.app" + WORKING_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY} + COMMAND_ERROR_IS_FATAL ANY + ) + + execute_process(COMMAND create-dmg --volname "@QGIS_APP_NAME@ Installer" --hide-extension @QGIS_APP_NAME@.app --volicon "@CMAKE_SOURCE_DIR@/images/icons/mac/qgis.icns" --background "@CMAKE_SOURCE_DIR@/platform/macos/installer_background.png" --window-pos 200 120 --window-size 512 320 --icon-size 100 --icon "@QGIS_APP_NAME@.app" 130 160 --app-drop-link 400 155 @CMAKE_BINARY_DIR@/@QGIS_APP_NAME@-Installer.dmg ${CPACK_TEMPORARY_DIRECTORY}/@QGIS_APP_NAME@.app + RESULT_VARIABLE CREATE_DMG_FAILURE) + + if(CREATE_DMG_FAILURE) + message(STATUS "Creating dmg failed.") + endif() +endif() diff --git a/platform/macos/Info.plist.in b/platform/macos/Info.plist.in new file mode 100644 index 00000000000..07436013814 --- /dev/null +++ b/platform/macos/Info.plist.in @@ -0,0 +1,329 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleName + QGIS + CFBundleIdentifier + org.qgis.qgis3 + CFBundleExecutable + @QGIS_APP_NAME@ + CFBundlePackageType + APPL + CFBundleSignature + QGIS + CFBundleGetInfoString + @QGIS_APP_NAME@ @COMPLETE_VERSION@-@RELEASE_NAME@ (@SHA@), © 2002-2019 QGIS Development Team + CFBundleShortVersionString + @COMPLETE_VERSION@ + CFBundleVersion + @COMPLETE_VERSION@ (@SHA@) + CFBundleIconFile + qgis.icns + CFBundleInfoDictionaryVersion + 6.0 + CSResourcesFileMapped + + CFBundleDocumentTypes + + + CFBundleTypeName + QGIS Project document + CFBundleTypeRole + Editor + CFBundleTypeIconFile + qgs.icns + CFBundleTypeExtensions + + qgs + + CFBundleTypeOSTypes + + QGIS + + + + CFBundleTypeName + QGIS Project zipped container + CFBundleTypeRole + Editor + CFBundleTypeIconFile + qgz.icns + CFBundleTypeExtensions + + qgz + + + + CFBundleTypeName + ESRI Shape document + CFBundleTypeRole + Editor + CFBundleTypeIconFile + shp.icns + CFBundleTypeExtensions + + shp + + + + CFBundleTypeName + SDTS document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + ddf.icns + CFBundleTypeExtensions + + ddf + + + + CFBundleTypeName + MapInfo document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + mif.icns + CFBundleTypeExtensions + + mif + + + + CFBundleTypeName + GML document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + gml.icns + CFBundleTypeExtensions + + gml + + + + CFBundleTypeName + GeoTIFF image + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + tiff.icns + CFBundleTypeExtensions + + tiff + tif + + CFBundleTypeMIMETypes + + image/tiff + + CFBundleTypeOSTypes + + TIFF + + + + CFBundleTypeName + ERDAS IMAGINE document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + img.icns + CFBundleTypeExtensions + + img + + + + CFBundleTypeName + Arc/Info ASCII Grid document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + asc.icns + CFBundleTypeExtensions + + asc + + + + CFBundleTypeName + DTED document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + dt0.icns + CFBundleTypeExtensions + + dt0 + + + + CFBundleTypeName + JPEG 2000 image + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + jp2.icns + CFBundleTypeExtensions + + jp2 + + CFBundleTypeMIMETypes + + image/jp2 + + CFBundleTypeOSTypes + + jp2 + + + + CFBundleTypeName + DEM document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + dem.icns + CFBundleTypeExtensions + + dem + + + + CFBundleTypeName + QGIS style document + CFBundleTypeRole + Editor + CFBundleTypeIconFile + qml.icns + CFBundleTypeExtensions + + qml + + + + CFBundleTypeName + Memory layer document + CFBundleTypeRole + Editor + CFBundleTypeIconFile + mldata.icns + CFBundleTypeExtensions + + mldata + + + + CFBundleTypeName + QGIS composer template + CFBundleTypeRole + Editor + CFBundleTypeIconFile + qpt.icns + CFBundleTypeExtensions + + qpt + + + + CFBundleTypeName + QGIS layer definition document + CFBundleTypeRole + Editor + CFBundleTypeIconFile + qlr.icns + CFBundleTypeExtensions + + qlr + + + + CFBundleTypeName + DXF document + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + dxf.icns + CFBundleTypeExtensions + + dxf + + + + CFBundleTypeName + SQLite database + CFBundleTypeRole + Editor + CFBundleTypeIconFile + sqlite.icns + CFBundleTypeExtensions + + sqlite + + + + CFBundleLocalizations + + en + af + ar + bg + ca_ES + cs_CZ + da_DK + de + el_GR + es + fa + fi + fr + gl_ES + he + hr_HR + hu + id + is + it + ja + ka_GE + ko_KR + lo + lt + lv + mn + nl + no + pl_PL + pt_BR + pt_PT + ro + ru + sk + sl_SI + sq_AL + sr_CS-Latn + sv + ta + th + tr + uk + vi + xh + zh_CN + zh_TW + + LSEnvironment + + QT_AUTO_SCREEN_SCALE_FACTOR + 1 + + NSPrincipalClass + NSApplication + NSHighResolutionCapable + True + + diff --git a/platform/macos/installer_background.png b/platform/macos/installer_background.png new file mode 100644 index 0000000000000000000000000000000000000000..949a05aadf2a19e068c49b9f5c6eba901d739df9 GIT binary patch literal 7061 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 literal 0 HcmV?d00001 diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index cf04c20710c..d84286985b7 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -91,7 +91,7 @@ ELSE() SET(BINDING_FILES_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) ENDIF() -set(QGIS_PYTHON_DIR ${Python_SITEARCH}/qgis) +set(QGIS_PYTHON_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis) # core module file(GLOB_RECURSE sip_files_core ${BINDING_FILES_ROOT_DIR}/core/*.sip ${BINDING_FILES_ROOT_DIR}/core/*.sip.in) diff --git a/python/PyQt/CMakeLists.txt b/python/PyQt/CMakeLists.txt index 8b062819d1a..099958ac3d7 100644 --- a/python/PyQt/CMakeLists.txt +++ b/python/PyQt/CMakeLists.txt @@ -1,4 +1,4 @@ -set (QGIS_PYQT_DIR ${Python_SITEARCH}/qgis/PyQt) +set (QGIS_PYQT_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis/PyQt) set(PYQT_COMPAT_FILES __init__.py diff --git a/python/processing/CMakeLists.txt b/python/processing/CMakeLists.txt index 81cd0be4a94..4ac96104ba8 100644 --- a/python/processing/CMakeLists.txt +++ b/python/processing/CMakeLists.txt @@ -1,6 +1,6 @@ # See ../CMakeLists.txt for info on staged-plugins* and clean-staged-plugins targets -set(QGIS_PYTHON_DIR ${Python_SITEARCH}/qgis) +set(QGIS_PYTHON_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis) set(PY_FILES __init__.py diff --git a/python/testing/CMakeLists.txt b/python/testing/CMakeLists.txt index c428e5e9359..38b9f7a89b8 100644 --- a/python/testing/CMakeLists.txt +++ b/python/testing/CMakeLists.txt @@ -1,6 +1,6 @@ # See ../CMakeLists.txt for info on staged-plugins* and clean-staged-plugins targets -set(QGIS_PYTHON_DIR ${Python_SITEARCH}/qgis) +set(QGIS_PYTHON_DIR ${QGIS_PYTHON_INSTALL_DIR}/qgis) set(PY_FILES __init__.py diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index 24158abb69d..73e73587ebf 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -351,8 +351,11 @@ void QgsApplication::init( QString profileFolder ) { if ( sPrefixPath()->isNull() ) { -#if defined(Q_OS_MACOS) || defined(Q_OS_WIN) +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) && !defined(QGIS_MAC_BUNDLE) setPrefixPath( applicationDirPath(), true ); +#elif defined(QGIS_MAC_BUNDLE) + QDir myDir( applicationDirPath() + QLatin1String( "/../.." ) ); + setPrefixPath( myDir.absolutePath(), true ); #elif defined(ANDROID) // this is "/data/data/org.qgis.qgis" in android QDir myDir( QDir::homePath() ); diff --git a/src/python/qgspythonutilsimpl.cpp b/src/python/qgspythonutilsimpl.cpp index 14facb8ea42..e59099bf70e 100644 --- a/src/python/qgspythonutilsimpl.cpp +++ b/src/python/qgspythonutilsimpl.cpp @@ -218,8 +218,27 @@ void QgsPythonUtilsImpl::init() } #endif - // initialize python - Py_Initialize(); + PyConfig config; + PyConfig_InitPythonConfig( &config ); + +#ifdef QGIS_MAC_BUNDLE + // If we package QGIS as a mac app, we deploy Qt plugins into [app]/Contents/PlugIns + if ( qgetenv( "PYTHONHOME" ).isNull() ) + { + status = PyConfig_SetString( &config, &config.home, QgsApplication::libraryPath().toStdWString().c_str() ); + if ( PyStatus_Exception( status ) ) + { + qWarning() << "Failed to set python home"; + } + } +#endif + + status = Py_InitializeFromConfig( &config ); + if ( PyStatus_Exception( status ) ) + { + qWarning() << "Failed to initialize from config"; + } + PyConfig_Clear( &config ); mPythonEnabled = true;