mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-23 00:02:38 -05:00
223 lines
10 KiB
CMake
223 lines
10 KiB
CMake
# QGIS Mac Bundle Macros
|
|
|
|
# BundleUtilities has functions to bundle and fixup libraries into an
|
|
# application package, but it's all-or-nothing and is missing some features:
|
|
#
|
|
# - @loader_path
|
|
# - helper functions can't get install_name, just dependencies
|
|
|
|
# the following cmakecache vars must be set, redefine them
|
|
# with config-file substitutions in install-run scripts:
|
|
#
|
|
# CPACK_PACKAGE_VERSION_MAJOR, CPACK_PACKAGE_VERSION_MINOR
|
|
# CMAKE_INSTALL_PREFIX, CMAKE_VERBOSE_MAKEFILE, CMAKE_BUILD_TYPE
|
|
# CMAKE_OSX_ARCHITECTURES
|
|
# QGIS_APP_NAME
|
|
# QGIS_MACAPP_PREFIX
|
|
# QGIS_*_SUBDIR, QGIS_*_SUBDIR_REV
|
|
# WITH_*
|
|
|
|
# this file must only be included after target installation is complete
|
|
|
|
# message only if verbose makefiles
|
|
|
|
FUNCTION (MYMESSAGE MSG)
|
|
IF (${CMAKE_VERBOSE_MAKEFILE})
|
|
MESSAGE (STATUS "${MSG}")
|
|
ENDIF (${CMAKE_VERBOSE_MAKEFILE})
|
|
ENDFUNCTION (MYMESSAGE)
|
|
|
|
# get the install_name of a library or framework
|
|
# regex stuff taken from GetPrerequisites
|
|
|
|
FUNCTION (GET_INSTALL_NAME LIBFILE LIBNAME OUTVAR)
|
|
IF (EXISTS "${LIBFILE}")
|
|
EXECUTE_PROCESS (COMMAND otool -L "${LIBFILE}" OUTPUT_VARIABLE iname_out)
|
|
# remove 1st line, it's just path to lib file
|
|
STRING (REGEX REPLACE ".*:\n" "" iname "${iname_out}")
|
|
IF (iname)
|
|
# find libname
|
|
STRING (REGEX MATCH "[^\n\t ]*${LIBNAME}[^\n]*" iname "${iname}")
|
|
STRING (REGEX REPLACE " \\(compatibility version .*, current version .*\\)" "" iname "${iname}")
|
|
ENDIF (iname)
|
|
SET (${OUTVAR} ${iname} PARENT_SCOPE)
|
|
ELSE ()
|
|
SET (${OUTVAR} "" PARENT_SCOPE)
|
|
ENDIF ()
|
|
ENDFUNCTION (GET_INSTALL_NAME)
|
|
|
|
# install_name_tool -change CHANGE CHANGETO CHANGEBIN
|
|
|
|
FUNCTION (INSTALLNAMETOOL_CHANGE CHANGE CHANGETO CHANGEBIN)
|
|
IF (EXISTS "${CHANGEBIN}" AND CHANGE AND CHANGETO)
|
|
# ensure CHANGEBIN is writable by user, e.g. Homebrew binaries are installed non-writable
|
|
EXECUTE_PROCESS (COMMAND chmod u+w "${CHANGEBIN}")
|
|
EXECUTE_PROCESS (COMMAND install_name_tool -change ${CHANGE} ${CHANGETO} "${CHANGEBIN}")
|
|
# if that didn't work, try a symlink-resolved id
|
|
# (some package systems, like Homebrew, heavily use symlinks; and, inter-package builds, like plugins,
|
|
# may point to the resolved location instead of the 'public' symlink installed to prefixes like /usr/local)
|
|
get_filename_component(_chgreal ${CHANGE} REALPATH)
|
|
EXECUTE_PROCESS (COMMAND install_name_tool -change ${_chgreal} ${CHANGETO} "${CHANGEBIN}")
|
|
ENDIF ()
|
|
ENDFUNCTION (INSTALLNAMETOOL_CHANGE)
|
|
|
|
# copy a framework, only specified archs, current version, debug dep on CMAKE_BUILD_TYPE
|
|
|
|
FUNCTION (COPY_FRAMEWORK FWPREFIX FWNAME FWDEST)
|
|
# reconstruct framework to avoid excessive copying, then deleting
|
|
# especially when debug variants are present
|
|
# find current version
|
|
# use python because pwd not working with WORKING_DIRECTORY param
|
|
EXECUTE_PROCESS (
|
|
COMMAND python -c "import os.path\nprint(os.path.realpath(\"${FWPREFIX}/${FWNAME}.framework/Versions/Current\"))"
|
|
OUTPUT_VARIABLE FWDIRPHYS
|
|
)
|
|
STRING (STRIP "${FWDIRPHYS}" FWDIRPHYS)
|
|
IF (IS_DIRECTORY "${FWDIRPHYS}")
|
|
STRING (REGEX MATCH "[^/\n]+$" FWVER "${FWDIRPHYS}")
|
|
EXECUTE_PROCESS (COMMAND mkdir -p "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}")
|
|
EXECUTE_PROCESS (COMMAND ln -sfn ${FWVER} "${FWDEST}/${FWNAME}.framework/Versions/Current")
|
|
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/${FWNAME}" "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}/${FWNAME}")
|
|
EXECUTE_PROCESS (COMMAND ln -sf Versions/Current/${FWNAME} "${FWDEST}/${FWNAME}.framework/${FWNAME}")
|
|
IF (IS_DIRECTORY "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/Resources")
|
|
EXECUTE_PROCESS (COMMAND cp -Rfp "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/Resources" "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}")
|
|
EXECUTE_PROCESS (COMMAND ln -sfn Versions/Current/Resources "${FWDEST}/${FWNAME}.framework/Resources")
|
|
ENDIF (IS_DIRECTORY "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/Resources")
|
|
# ensure writable by user, e.g. Homebrew frameworks are installed non-writable
|
|
EXECUTE_PROCESS (COMMAND chmod -R u+w "${FWDEST}/${FWNAME}.framework")
|
|
EXECUTE_PROCESS (COMMAND install_name_tool -id "${ATEXECUTABLE}/${QGIS_FW_SUBDIR}/${FWNAME}" "${FWDEST}/${FWNAME}.framework/${FWNAME}")
|
|
# debug variants
|
|
SET (FWD "${FWNAME}_debug")
|
|
IF ("${FWDEBUG}" STREQUAL "Debug" AND EXISTS "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/${FWD}")
|
|
EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${FWPREFIX}/${FWNAME}.framework/Versions/${FWVER}/${FWD}" "${FWDEST}/${FWNAME}.framework/Versions/${FWVER}/${FWD}")
|
|
EXECUTE_PROCESS (COMMAND ln -sf Versions/Current/${FWD} "${FWDEST}/${FWNAME}.framework/${FWD}")
|
|
IF (IS_DIRECTORY "${FWPREFIX}/${FWNAME}.framework/${FWD}.dSYM")
|
|
EXECUTE_PROCESS (COMMAND ditto -X ${QARCHS} "${FWPREFIX}/${FWNAME}.framework/${FWD}.dSYM" "${FWDEST}/${FWNAME}.framework")
|
|
ENDIF ()
|
|
ENDIF ()
|
|
ENDIF ()
|
|
ENDFUNCTION (COPY_FRAMEWORK)
|
|
|
|
# update a library path in all QGIS binary files
|
|
# if dylib, change LIBFROM to LIBTO as is
|
|
# else assumes it's a framework, change LIBFROM to LIBTO.framework/LIBTO
|
|
|
|
FUNCTION (UPDATEQGISPATHS LIBFROM LIBTO)
|
|
IF (LIBFROM)
|
|
STRING (REGEX MATCH "\\.(dylib|so)$" ISLIB "${LIBTO}")
|
|
IF (ISLIB)
|
|
SET (LIBPOST "${LIBTO}")
|
|
SET (LIBMID "${QGIS_LIB_SUBDIR}")
|
|
ElSE ()
|
|
SET (LIBPOST "${LIBTO}.framework/${LIBTO}")
|
|
SET (LIBMID "${QGIS_FW_SUBDIR}")
|
|
ENDIF ()
|
|
SET (LIB_CHG_TO "${ATEXECUTABLE}/${LIBMID}/${LIBPOST}")
|
|
# app - always @executable_path
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QAPPDIR}/${QGIS_APP_NAME}")
|
|
# qgis helper apps - don't link anything else than Qt/Qgis
|
|
FOREACH (QA ${QGAPPLIST})
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QBINDIR}/${QA}.app/Contents/MacOS/${QA}")
|
|
ENDFOREACH (QA)
|
|
# qgis-mapserver
|
|
IF (${WITH_SERVER})
|
|
SET (LIB_CHG_TO "${ATEXECUTABLE}/${QGIS_CGIBIN_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QCGIDIR}/qgis_mapserv.fcgi")
|
|
ENDIF ()
|
|
# libs
|
|
# bundled frameworks can use short relative path
|
|
IF (ISLIB)
|
|
SET (LIB_CHG_TO "${ATLOADER}/../../../${QGIS_FW_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
ElSE ()
|
|
SET (LIB_CHG_TO "${ATLOADER}/../../../${LIBPOST}")
|
|
ENDIF ()
|
|
FOREACH (QL ${QGFWLIST})
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QFWDIR}/${QL}.framework/${QL}")
|
|
ENDFOREACH (QL)
|
|
# non-framework qgis libs
|
|
SET (LIB_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
FOREACH (QL ${QGLIBLIST})
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QLIBDIR}/${QL}")
|
|
ENDFOREACH (QL)
|
|
# crssync
|
|
SET (LIB_CHG_TO "${ATEXECUTABLE}/${QGIS_LIBEXEC_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QLIBXDIR}/crssync")
|
|
# GRASS libexec stuff
|
|
FOREACH (QG ${QGRASSEXECLIST})
|
|
IF (EXISTS "${QLIBXDIR}/grass/${QG}")
|
|
SET (LIB_CHG_TO "${ATLOADER}/../../${QGIS_LIBEXEC_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QLIBXDIR}/grass/${QG}")
|
|
ENDIF ()
|
|
ENDFOREACH (QG)
|
|
# plugins
|
|
SET (LIB_CHG_TO "${ATLOADER}/${QGIS_PLUGIN_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
FOREACH (QP ${QGPLUGLIST})
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QP}")
|
|
ENDFOREACH (QP)
|
|
# quick plugin
|
|
SET (LIB_CHG_TO "${ATLOADER}/../../${LIBMID}/${LIBPOST}")
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QAPPDIR}/qml/QgsQuick/libqgis_quick_plugin.dylib")
|
|
# qgis python
|
|
SET (LIB_CHG_TO "${ATLOADER}/../../${QGIS_DATA_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
FOREACH (PG ${QGPYLIST})
|
|
INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${PG}")
|
|
ENDFOREACH (PG)
|
|
# bin - nothing yet
|
|
# SET (LIB_CHG_TO "${ATLOADER}/${QGIS_BIN_SUBDIR_REV}/${LIBMID}/${LIBPOST}")
|
|
#FOREACH (PB ...)
|
|
# INSTALLNAMETOOL_CHANGE ("${LIBFROM}" "${LIB_CHG_TO}" "${QBINDIR}/${PB}")
|
|
#ENDFOREACH (PB)
|
|
ENDIF (LIBFROM)
|
|
ENDFUNCTION (UPDATEQGISPATHS)
|
|
|
|
|
|
# Find directory path for a known Python module (or package) directory or file name
|
|
# see: PYTHON_MODULE_PATHS in 0vars.cmake.in
|
|
FUNCTION (PYTHONMODULEDIR MOD_NAME OUTVAR)
|
|
FOREACH (MOD_PATH ${PYTHON_MODULE_PATHS})
|
|
IF (EXISTS "${MOD_PATH}/${MOD_NAME}")
|
|
SET (${OUTVAR} "${MOD_PATH}" PARENT_SCOPE)
|
|
RETURN()
|
|
ENDIF()
|
|
ENDFOREACH (MOD_PATH)
|
|
SET (${OUTVAR} "" PARENT_SCOPE)
|
|
ENDFUNCTION (PYTHONMODULEDIR)
|
|
|
|
|
|
SET (ATEXECUTABLE "@executable_path")
|
|
SET (ATLOADER "@loader_path")
|
|
SET (Q_FWVER ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR})
|
|
|
|
# install destinations
|
|
SET (QAPPDIRC "$ENV{DESTDIR}${QGIS_MACAPP_PREFIX}")
|
|
SET (QAPPDIR "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}")
|
|
SET (QFWDIR "${QAPPDIR}/${QGIS_FW_SUBDIR}")
|
|
SET (QBINDIR "${QAPPDIR}/${QGIS_BIN_SUBDIR}")
|
|
SET (QCGIDIR "${QAPPDIR}/${QGIS_CGIBIN_SUBDIR}")
|
|
SET (QLIBDIR "${QAPPDIR}/${QGIS_LIB_SUBDIR}")
|
|
SET (QLIBXDIR "${QAPPDIR}/${QGIS_LIBEXEC_SUBDIR}")
|
|
SET (QDATADIR "${QAPPDIR}/${QGIS_DATA_SUBDIR}")
|
|
SET (QPLUGDIR "${QAPPDIR}/${QGIS_PLUGIN_SUBDIR}")
|
|
SET (QGISPYDIR "${QAPPDIR}/${QGIS_DATA_SUBDIR}/python")
|
|
|
|
# build arches
|
|
SET (QARCHS "")
|
|
FOREACH (QARCH ${CMAKE_OSX_ARCHITECTURES})
|
|
SET (QARCHS ${QARCHS} "--arch" "${QARCH}")
|
|
ENDFOREACH (QARCH)
|
|
|
|
# common file lists
|
|
FILE (GLOB QGFWLIST RELATIVE "${QFWDIR}" "${QFWDIR}/qgis*.framework")
|
|
# for some reason, REPLACE is stripping list seps
|
|
STRING(REPLACE ".framework" ";" QGFWLIST ${QGFWLIST})
|
|
# don't collect any library symlinks, limit to versioned libs
|
|
SET (Q_LIBVER ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR})
|
|
FILE (GLOB QGLIBLIST RELATIVE "${QLIBDIR}" "${QLIBDIR}/libqgis*.dylib" "${QLIBDIR}/qgis/server/lib*.so")
|
|
FILE (GLOB QGPLUGLIST "${QPLUGDIR}/*.so")
|
|
FILE (GLOB QGPYLIST "${QGISPYDIR}/qgis/*.so")
|
|
FILE (GLOB QGAPPLIST RELATIVE "${QBINDIR}" "${QBINDIR}/q*.app")
|
|
FILE (GLOB QGRASSEXECLIST RELATIVE "${QLIBXDIR}/grass" "${QLIBXDIR}/grass/*/*")
|
|
IF (QGAPPLIST)
|
|
STRING(REPLACE ".app" ";" QGAPPLIST ${QGAPPLIST})
|
|
ENDIF (QGAPPLIST)
|