# 1qt - bundle Qt frameworks and PyQt # ! cmakecache vars not available to external scripts # so we configure it first to do substitutions # make sure to use @varname@ # kill boolean warnings CMAKE_POLICY (SET CMP0012 NEW) 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") # Qt framework version is major version SET (QT_FWVER @QT_VERSION_MAJOR@) # so config-file doesn't try to replace @ SET (ATEXECUTABLE "@executable_path") SET (ATLOADER "@loader_path") INCLUDE (@CMAKE_SOURCE_DIR@/cmake/MacBundleMacros.cmake) # build list of Qt frameworks to bundle SET (QTLISTQG QtCore QtGui phonon) SET (PYQTLIST Qt QtCore QtGui phonon) IF (@QT_USE_QTXML@) SET (QTLISTQG ${QTLISTQG} QtXml) SET (PYQTLIST ${PYQTLIST} QtXml) ENDIF (@QT_USE_QTXML@) IF (@QT_USE_QTNETWORK@) SET (QTLISTQG ${QTLISTQG} QtNetwork) SET (PYQTLIST ${PYQTLIST} QtNetwork) ENDIF (@QT_USE_QTNETWORK@) IF (@QT_USE_QTSVG@) SET (QTLISTQG ${QTLISTQG} QtSvg) SET (PYQTLIST ${PYQTLIST} QtSvg) ENDIF (@QT_USE_QTSVG@) IF (@QT_USE_QTSQL@) SET (QTLISTQG ${QTLISTQG} QtSql) SET (PYQTLIST ${PYQTLIST} QtSql) ENDIF (@QT_USE_QTSQL@) IF (@QT_USE_QTWEBKIT@) SET (QTLISTQG ${QTLISTQG} QtWebKit) SET (PYQTLIST ${PYQTLIST} QtWebKit) # see if it links QtDBus EXECUTE_PROCESS (COMMAND otool -L @QT_QTWEBKIT_LIBRARY@/QtWebKit OUTPUT_VARIABLE QTWEBKIT_DBUS) IF (QTWEBKIT_DBUS MATCHES ".*QtDBus.framework.*") SET (QTLISTQG ${QTLISTQG} QtDBus) ENDIF () # see if it links QtXmlPatterns EXECUTE_PROCESS (COMMAND otool -L @QT_QTWEBKIT_LIBRARY@/QtWebKit OUTPUT_VARIABLE QTWEBKIT_XMLP) IF (QTWEBKIT_XMLP MATCHES ".*QtXmlPatterns.framework.*") SET (QTLISTQG ${QTLISTQG} QtXmlPatterns) SET (PYQTLIST ${PYQTLIST} QtXmlPatterns) ENDIF () ENDIF (@QT_USE_QTWEBKIT@) MYMESSAGE ("Qt list: ${QTLISTQG}") # qt arches FOREACH (QARCH @CMAKE_OSX_ARCHITECTURES@) SET (QARCHS ${QARCHS} "--arch" "${QARCH}") ENDFOREACH (QARCH) MYMESSAGE("Archs: ${QARCHS}") # symlinks when only @executable_path used IF (NOT @OSX_HAVE_LOADERPATH@) EXECUTE_PROCESS (COMMAND ln -sfh ../Frameworks "${QAPPDIR}/") IF (IS_DIRECTORY "${QLIBXIR}/grass/bin") EXECUTE_PROCESS (COMMAND ln -sfh ../@QGIS_LIBEXEC_SUBDIR_REV@/@QGIS_FW_SUBDIR@ "${QLIBXDIR}/grass/Frameworks") ENDIF () EXECUTE_PROCESS (COMMAND ln -sfh @QGIS_CGIBIN_SUBDIR_REV@/@QGIS_LIB_SUBDIR@ "${QCGIDIR}/lib") ENDIF (NOT @OSX_HAVE_LOADERPATH@) # Qt frameworks MESSAGE (STATUS "Copying Qt frameworks...") EXECUTE_PROCESS (COMMAND mkdir -p "${QFWDIR}") FOREACH (QFW ${QTLISTQG}) IF (NOT IS_DIRECTORY "${QFWDIR}/${QFW}.framework") # reconstruct framework to avoid excessive copying, then deleting # especially when debug variants are present EXECUTE_PROCESS (COMMAND mkdir -p "${QFWDIR}/${QFW}.framework/Versions/${QT_FWVER}") EXECUTE_PROCESS (COMMAND ln -sfh ${QT_FWVER} "${QFWDIR}/${QFW}.framework/Versions/Current") MYMESSAGE ("ditto ${QARCHS} \"@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/${QFW}\" \"${QFWDIR}/${QFW}.framework/Versions/${QT_FWVER}/${QFW}\"") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/${QFW}" "${QFWDIR}/${QFW}.framework/Versions/${QT_FWVER}/${QFW}") EXECUTE_PROCESS (COMMAND ln -sf Versions/Current/${QFW} "${QFWDIR}/${QFW}.framework/${QFW}") IF (IS_DIRECTORY "@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/Resources") EXECUTE_PROCESS (COMMAND cp -Rfp "@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/Resources" "${QFWDIR}/${QFW}.framework/Versions/${QT_FWVER}") EXECUTE_PROCESS (COMMAND ln -sfh Versions/Current/Resources "${QFWDIR}/${QFW}.framework/Resources") ENDIF (IS_DIRECTORY "@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/Resources") # debug variants SET (QFWD "${QFW}_debug") IF ("@CMAKE_BUILD_TYPE@" STREQUAL "Debug" AND EXISTS "@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/${QFWD}") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_LIBRARY_DIR@/${QFW}.framework/Versions/${QT_FWVER}/${QFWD}" "${QFWDIR}/${QFW}.framework/Versions/${QT_FWVER}/${QFWD}") EXECUTE_PROCESS (COMMAND ln -sf Versions/Current/${QFWD} "${QFWDIR}/${QFW}.framework/${QFWD}") IF (IS_DIRECTORY "@QT_LIBRARY_DIR@/${QFW}.framework/${QFWD}.dSYM") EXECUTE_PROCESS (COMMAND ditto -X ${QARCHS} "@QT_LIBRARY_DIR@/${QFW}.framework/${QFWD}.dSYM" "${QFWDIR}/${QFW}.framework") ENDIF () ENDIF () ENDIF () ENDFOREACH (QFW) # Qt plugins EXECUTE_PROCESS (COMMAND mkdir -p "${QAPPDIRC}/PlugIns/imageformats") IF (NOT EXISTS "${QAPPDIRC}/PlugIns/imageformats/libqjpeg.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/imageformats/libqjpeg.dylib" "${QAPPDIRC}/PlugIns/imageformats/libqjpeg.dylib") ENDIF () EXECUTE_PROCESS (COMMAND mkdir -p "${QAPPDIRC}/PlugIns/codecs") FOREACH (QTC cn;jp;kr;tw) IF (NOT EXISTS "${QAPPDIRC}/PlugIns/codecs/libq${QTC}codecs.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/codecs/libq${QTC}codecs.dylib" "${QAPPDIRC}/PlugIns/codecs/libq${QTC}codecs.dylib") ENDIF () ENDFOREACH (QTC) # Qwt # assumes shared libraries MESSAGE (STATUS "Copying Qwt and updating library paths...") IF (NOT EXISTS "${QLIBDIR}/libqwt.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QWT_LIBRARY@" "${QLIBDIR}/libqwt.dylib") GET_INSTALL_NAME ("@QWT_LIBRARY@" "libqwt" QLIB) IF (QLIB) SET (QWT_CHG "${QLIB}") # default for Qgis and no loader_path SET (QWT_CHG_TO "${ATEXECUTABLE}/@QGIS_LIB_SUBDIR@/libqwt.dylib") INSTALLNAMETOOL_CHANGE (${QWT_CHG} ${QWT_CHG_TO} "${QAPPDIR}/Qgis") ENDIF (QLIB) ENDIF () # PyQt MESSAGE (STATUS "Copying PyQt...") IF (NOT EXISTS "${QGISPYDIR}/sip.so") MYMESSAGE ("ditto ${QARCHS} \"@SIP_MOD_DIR@/sip.so\" \"${QGISPYDIR}/\"") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@SIP_MOD_DIR@/sip.so" "${QGISPYDIR}/") EXECUTE_PROCESS (COMMAND cp -fp "@SIP_MOD_DIR@/sipconfig.py" "${QGISPYDIR}/") ENDIF () # for now assume "PyQt4" next to SIP EXECUTE_PROCESS (COMMAND mkdir -p "${QGISPYDIR}/PyQt${QT_FWVER}") FOREACH (PQ ${PYQTLIST}) IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/${PQ}.so") MYMESSAGE ("ditto ${QARCHS} \"@SIP_MOD_DIR@/PyQt${QT_FWVER}/${PQ}.so\" \"${QGISPYDIR}/PyQt${QT_FWVER}/${PQ}.so\"") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@SIP_MOD_DIR@/PyQt${QT_FWVER}/${PQ}.so" "${QGISPYDIR}/PyQt${QT_FWVER}/${PQ}.so") ENDIF () ENDFOREACH (PQ) FILE (GLOB PQPYLIST "@SIP_MOD_DIR@/PyQt${QT_FWVER}/*.py") FOREACH (PQPY ${PQPYLIST}) EXECUTE_PROCESS (COMMAND cp -fp "${PQPY}" "${QGISPYDIR}/PyQt${QT_FWVER}/") ENDFOREACH (PQPY) EXECUTE_PROCESS (COMMAND cp -Rfp "@SIP_MOD_DIR@/PyQt${QT_FWVER}/uic" "${QGISPYDIR}/PyQt${QT_FWVER}") # PyQt utilities FOREACH (PU pylupdate4;pyrcc4) IF (NOT EXISTS "${QBINDIR}/${PU}") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@PYQT4_BIN_DIR@/${PU}" "${QBINDIR}/") ENDIF () ENDFOREACH (PU) IF (NOT EXISTS "${QBINDIR}/pyuic4") EXECUTE_PROCESS (COMMAND sed -E "s, /.*/PyQt4/uic/pyuic.py, ${QDATADIR}/python/PyQt4/uic/pyuic.py," "@PYQT4_BIN_DIR@/pyuic4" OUTPUT_VARIABLE PYUIC_CONTENTS) FILE (WRITE "${QBINDIR}/pyuic4" "${PYUIC_CONTENTS}") EXECUTE_PROCESS (COMMAND chmod +x "${QBINDIR}/pyuic4") ENDIF () # PyQwt MESSAGE (STATUS "Copying PyQwt and updating library paths...") EXECUTE_PROCESS (COMMAND mkdir -p "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5") IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/_iqt.so") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@SIP_MOD_DIR@/PyQt${QT_FWVER}/Qwt5/_iqt.so" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/") ENDIF () IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/Qwt.so") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@SIP_MOD_DIR@/PyQt${QT_FWVER}/Qwt5/Qwt.so" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/") ENDIF () FILE (GLOB PQWPYLIST "@SIP_MOD_DIR@/PyQt${QT_FWVER}/Qwt5/*.py") FOREACH (PQWPY ${PQWPYLIST}) EXECUTE_PROCESS (COMMAND cp -fp "${PQWPY}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/") ENDFOREACH (PQWPY) IF (QWT_CHG) IF (@OSX_HAVE_LOADERPATH@ AND QWT_CHG) SET (QWT_CHG_TO "${ATLOADER}/../../../@QGIS_DATA_SUBDIR_REV@/@QGIS_LIB_SUBDIR@/libqwt.dylib") ENDIF (@OSX_HAVE_LOADERPATH@ AND QWT_CHG) FOREACH (PW _iqt;Qwt) INSTALLNAMETOOL_CHANGE (${QWT_CHG} ${QWT_CHG_TO} "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so") ENDFOREACH (PW) ENDIF (QWT_CHG) # don't load plugins from system-installed Qt FILE (WRITE "${QAPPDIRC}/Resources/qt.conf" "") FILE (WRITE "${QBINDIR}/qgis_help.app/Contents/Resources/qt.conf" "") FILE (GLOB QGLIBLIST ${QLIBDIR}/libqgis*.dylib) FILE (GLOB QGPLUGLIST ${QPLUGDIR}/*.so) FILE (GLOB QGPYLIST ${QGISPYDIR}/qgis/*.so) # main Qt framework loop MESSAGE (STATUS "Updating Qt library paths...") FOREACH (QFW ${QTLISTQG}) # get install names from installed in case bundled copy already changed # from a previous install attempt GET_INSTALL_NAME ("@QT_LIBRARY_DIR@/${QFW}.framework/${QFW}" ${QFW}.framework QQ) SET (QFW_CHG "${QQ}") SET (QFW_CHG_TO "${ATEXECUTABLE}/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") # app - always @executable_path INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QAPPDIR}/Qgis") # qgis_help - use symlink, even when have loader_path, # applications behave better that way INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QBINDIR}/qgis_help.app/Contents/MacOS/qgis_help") # qgis-mapserver IF (@WITH_MAPSERVER@) IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATEXECUTABLE}/@QGIS_CGIBIN_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QCGIDIR}/qgis_mapserv.fcgi") ENDIF () # libs IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/@QGIS_LIB_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) FOREACH (QL ${QGLIBLIST}) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QL}") ENDFOREACH (QL) # Qwt INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QLIBDIR}/libqwt.dylib") # GRASS libexec stuff IF (EXISTS "${QLIBXDIR}/grass/bin/qgis.g.browser") IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../@QGIS_LIBEXEC_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QLIBXDIR}/grass/bin/qgis.g.browser") ENDIF () # plugins IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/@QGIS_PLUGIN_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) FOREACH (QP ${QGPLUGLIST}) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QP}") ENDFOREACH (QP) # qt plugs - same relative path INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QAPPDIRC}/PlugIns/imageformats/libqjpeg.dylib") FOREACH (QC cn;jp;kr;tw) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QAPPDIRC}/PlugIns/codecs/libq${QC}codecs.dylib") ENDFOREACH (QC) # qt fw IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../../${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) FOREACH (QF ${QTLISTQG}) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QFWDIR}/${QF}.framework/${QF}") ENDFOREACH (QF) # PyQt IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../@QGIS_DATA_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) FOREACH (PQ ${PYQTLIST}) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QGISPYDIR}/PyQt${QT_FWVER}/${PQ}.so") ENDFOREACH (PQ) # qgis python FOREACH (PG ${QGPYLIST}) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${PG}") ENDFOREACH (PG) # PyQwt IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../../@QGIS_DATA_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") ENDIF (@OSX_HAVE_LOADERPATH@) FOREACH (PW _iqt;Qwt) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so") ENDFOREACH (PW) # bin - PyQt utils SET (QFW_CHG_TO "${ATEXECUTABLE}/@QGIS_BIN_SUBDIR_REV@/@QGIS_FW_SUBDIR@/${QFW}.framework/${QFW}") FOREACH (PB pylupdate4;pyrcc4) INSTALLNAMETOOL_CHANGE (${QFW_CHG} ${QFW_CHG_TO} "${QBINDIR}/${PB}") ENDFOREACH (PB) ENDFOREACH (QFW)