# 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) INCLUDE ("@CMAKE_BINARY_DIR@/mac/0vars.cmake") INCLUDE ("@CMAKE_SOURCE_DIR@/cmake/MacBundleMacros.cmake") # Qt framework version is major version SET (QT_FWVER @QT_VERSION_MAJOR@) # build list of Qt frameworks to bundle # core list, includes dependencies SET (QTLISTQG QtCore QtGui phonon QtXml QtNetwork QtSvg QtSql QtWebKit QtXmlPatterns) SET (PYQTLIST Qt QtCore QtGui phonon QtXml QtNetwork QtSvg QtSql QtWebKit QtXmlPatterns) # see if QtWebKit 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 () # additional Qt may be needed by plugins SET (QTLISTQG ${QTLISTQG} QtMultimedia QtOpenGL) SET (PYQTLIST ${PYQTLIST} QtMultimedia QtOpenGL) # add Qsci.so, if available IF (@QSCI_FOUND@) SET (PYQTLIST ${PYQTLIST} Qsci) ENDIF (@QSCI_FOUND@) # for tests IF (ENABLE_TESTS) SET (QTLISTQG ${QTLISTQG} QtTest) SET (PYQTLIST ${PYQTLIST} QtTest) ENDIF () MYMESSAGE ("Qt list: ${QTLISTQG}") # 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@) ### copy files # Qt frameworks MESSAGE (STATUS "Copying Qt frameworks...") EXECUTE_PROCESS (COMMAND mkdir -p "${QFWDIR}") FOREACH (QFW ${QTLISTQG}) IF (NOT IS_DIRECTORY "${QFWDIR}/${QFW}.framework") COPY_FRAMEWORK("@QT_LIBRARY_DIR@" ${QFW} "${QFWDIR}") ENDIF () ENDFOREACH (QFW) # Qt plugins EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../imageformats") FOREACH (QI qgif;qico;qjpeg;qsvg;qtiff) IF (NOT EXISTS "${QPLUGDIR}/../imageformats/lib${QI}.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/imageformats/lib${QI}.dylib" "${QPLUGDIR}/../imageformats/lib${QI}.dylib") ENDIF () ENDFOREACH (QI) EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../codecs") FOREACH (QTC cn;jp;kr;tw) IF (NOT EXISTS "${QPLUGDIR}/../codecs/libq${QTC}codecs.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/codecs/libq${QTC}codecs.dylib" "${QPLUGDIR}/../codecs/libq${QTC}codecs.dylib") ENDIF () ENDFOREACH (QTC) EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../sqldrivers") IF (NOT EXISTS "${QPLUGDIR}/../sqldrivers/libqsqlite.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/sqldrivers/libqsqlite.dylib" "${QPLUGDIR}/../sqldrivers/libqsqlite.dylib") ENDIF () EXECUTE_PROCESS (COMMAND mkdir -p "${QPLUGDIR}/../iconengines") IF (NOT EXISTS "${QPLUGDIR}/../iconengines/libqsvgicon.dylib") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QT_PLUGINS_DIR@/iconengines/libqsvgicon.dylib" "${QPLUGDIR}/../iconengines/libqsvgicon.dylib") ENDIF () # Qwt STRING (REGEX MATCH "\\.dylib$" ISLIB "@QWT_LIBRARY@") STRING (REGEX MATCH "qwt.framework" ISFW "@QWT_LIBRARY@") IF (ISLIB) # 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") ENDIF () GET_INSTALL_NAME ("@QWT_LIBRARY@" "libqwt" QWT_CHG) IF (QWT_CHG) UPDATEQGISPATHS (${QWT_CHG} libqwt.dylib) ENDIF (QWT_CHG) ELSEIF (ISFW AND EXISTS "@QWT_LIBRARY@") # framework MESSAGE (STATUS "Copying Qwt framework and updating library paths...") IF (NOT IS_DIRECTORY "${QFWDIR}/qwt.framework") STRING(REGEX REPLACE "/qwt.framework.*" "" QWT_PARENT "@QWT_LIBRARY@") COPY_FRAMEWORK("${QWT_PARENT}" "qwt" "${QFWDIR}") ENDIF () GET_INSTALL_NAME ("@QWT_LIBRARY@" "qwt" QWT_CHG) IF (QWT_CHG) UPDATEQGISPATHS (${QWT_CHG} qwt) ENDIF (QWT_CHG) ENDIF (ISLIB) # QScintilla2 IF (@QSCINTILLA_FOUND@) STRING (REGEX MATCH "\\.dylib$" QSCILIB "@QSCINTILLA_LIBRARY@") IF (QSCILIB) # shared library MESSAGE (STATUS "Copying QScintilla2 and updating library paths...") IF (NOT EXISTS "${QLIBDIR}/libqscintilla2.dylib") # ditto should copy most current dylib from any symlink EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "@QSCINTILLA_LIBRARY@" "${QLIBDIR}/") STRING(REGEX REPLACE "/libqscintilla2.*" "" QSCI_PARENT "@QSCINTILLA_LIBRARY@") FILE (GLOB QSCI_LIST "${QSCI_PARENT}/libqscintilla2*") FOREACH (QSCI_DYLIB ${QSCI_LIST}) IF (IS_SYMLINK "${QSCI_DYLIB}") # for symlinks, which are ignored by ditto EXECUTE_PROCESS (COMMAND cp -a "${QSCI_DYLIB}" "${QLIBDIR}/") ENDIF () ENDFOREACH (QSCI_DYLIB) ENDIF () GET_INSTALL_NAME ("@QSCINTILLA_LIBRARY@" "libqscintilla2" QSCI_CHG) IF (QSCI_CHG) STRING(REGEX REPLACE ".*(libqscintilla2.*\\.dylib)$" "\\1" QSCI_CHG_NAME "${QSCI_CHG}") UPDATEQGISPATHS (${QSCI_CHG} ${QSCI_CHG_NAME}) ENDIF (QSCI_CHG) ENDIF (QSCILIB) ENDIF (@QSCINTILLA_FOUND@) # 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 () # if PYQT4_MOD_DIR not defined, assume "PyQt4" next to SIP SET(PYQT4MODDIR "@SIP_MOD_DIR@/PyQt${QT_FWVER}") IF (EXISTS "@PYQT4_MOD_DIR@") SET(PYQT4MODDIR "@PYQT4_MOD_DIR@") # MESSAGE (STATUS "Defined PYQT4_MOD_DIR: @PYQT4_MOD_DIR@") ENDIF () # also search python site-packages/PyQt4, in case module packages installed elsewhere and symlinked # (common with binary installers like homebrew) SET(PYQT4MODALT "@PYTHON_SITE_PACKAGES_SYS@/PyQt4") #MESSAGE (STATUS "Defined PYQT4MODALT: ${PYQT4MODALT}") EXECUTE_PROCESS (COMMAND mkdir -p "${QGISPYDIR}/PyQt${QT_FWVER}") FOREACH (PQ ${PYQTLIST}) SET(MODNAME "${PQ}.so") IF(EXISTS "${PYQT4MODDIR}/${MODNAME}") SET(PYQT4MOD "${PYQT4MODDIR}/${MODNAME}") ELSEIF(EXISTS "${PYQT4MODALT}/${MODNAME}") SET(PYQT4MOD "${PYQT4MODALT}/${MODNAME}") ENDIF() IF (EXISTS "${PYQT4MOD}") IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/${MODNAME}") # MESSAGE (STATUS "ditto ${QARCHS} \"${PYQT4MOD}\" \"${QGISPYDIR}/PyQt${QT_FWVER}/${MODNAME}\"") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${PYQT4MOD}" "${QGISPYDIR}/PyQt${QT_FWVER}/${MODNAME}") ENDIF () ELSE (EXISTS "${PYQT4MOD}") MESSAGE (STATUS "PyQt4 module ${MODNAME} not found") ENDIF (EXISTS "${PYQT4MOD}") UNSET(PYQT4MOD) ENDFOREACH (PQ) FILE (GLOB PQPYLIST "${PYQT4MODDIR}/*.py") FOREACH (PQPY ${PQPYLIST}) EXECUTE_PROCESS (COMMAND cp -fp "${PQPY}" "${QGISPYDIR}/PyQt${QT_FWVER}/") ENDFOREACH (PQPY) EXECUTE_PROCESS (COMMAND cp -Rfp "${PYQT4MODDIR}/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, \"\$(/usr/bin/dirname \"\$0\")/../../Resources/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 # only if it's available, not compatible with newer PyQt IF (EXISTS "${PYQT4MODDIR}/Qwt5/_iqt.so") 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} "${PYQT4MODDIR}/Qwt5/_iqt.so" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/") ENDIF () IF (NOT EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/Qwt.so") EXECUTE_PROCESS (COMMAND ditto ${QARCHS} "${PYQT4MODDIR}/Qwt5/Qwt.so" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/") ENDIF () FILE (GLOB PQWPYLIST "${PYQT4MODDIR}/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@) SET (QWT_CHG_TO "${ATLOADER}/../../../@QGIS_DATA_SUBDIR_REV@/@QGIS_LIB_SUBDIR@/libqwt.dylib") ENDIF (@OSX_HAVE_LOADERPATH@) FOREACH (PW _iqt;Qwt) INSTALLNAMETOOL_CHANGE ("${QWT_CHG}" "${QWT_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so") ENDFOREACH (PW) ENDIF (QWT_CHG) ENDIF () # QScintilla Python module # should have already been copied with PyQt modules IF (EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qsci.so") MESSAGE (STATUS "Updating QScintilla2 Python module library paths...") IF (QSCI_CHG AND QSCI_CHG_NAME) IF (@OSX_HAVE_LOADERPATH@) SET (QSCI_CHG_TO "${ATLOADER}/../../@QGIS_DATA_SUBDIR_REV@/@QGIS_LIB_SUBDIR@/${QSCI_CHG_NAME}") ENDIF (@OSX_HAVE_LOADERPATH@) INSTALLNAMETOOL_CHANGE ("${QSCI_CHG}" "${QSCI_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qsci.so") ENDIF (QSCI_CHG AND QSCI_CHG_NAME) ENDIF () # don't load plugins from system-installed Qt FILE (WRITE "${QAPPDIRC}/Resources/qt.conf" "") FOREACH (QA ${QGAPPLIST}) FILE (WRITE "${QBINDIR}/${QA}.app/Contents/Resources/qt.conf" "") ENDFOREACH (QA) ### update lib paths 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}") # qgis stuff UPDATEQGISPATHS ("${QFW_CHG}" ${QFW}) SET (LIBPOST "${QFW}.framework/${QFW}") # Qwt STRING (REGEX MATCH "\\.dylib$" ISLIB "@QWT_LIBRARY@") STRING (REGEX MATCH "qwt.framework" ISFW "@QWT_LIBRARY@") IF (ISLIB) IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}") ENDIF () INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/libqwt.dylib") ELSEIF (ISFW AND EXISTS "${QFWDIR}/qwt.framework/qwt") IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}") ENDIF () INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/qwt.framework/qwt") ENDIF (ISLIB) # QScintilla2 IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/${QGIS_LIB_SUBDIR_REV}/${QGIS_FW_SUBDIR}/${LIBPOST}") ENDIF () INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QLIBDIR}/libqscintilla2.dylib") # qt plugs IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/@QGIS_PLUGIN_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}") ENDIF () FOREACH (QI qgif;qico;qjpeg;qsvg;qtiff) INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../imageformats/lib${QI}.dylib") ENDFOREACH (QI) FOREACH (QC cn;jp;kr;tw) INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../codecs/libq${QC}codecs.dylib") ENDFOREACH (QC) INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../sqldrivers/libqsqlite.dylib") INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QPLUGDIR}/../iconengines/libqsvgicon.dylib") # qt fw IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../../${LIBPOST}") ENDIF () FOREACH (QF ${QTLISTQG}) INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QFWDIR}/${QF}.framework/${QF}") ENDFOREACH (QF) # PyQt (includes QScintilla2 module) IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../@QGIS_DATA_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}") ENDIF () FOREACH (PQ ${PYQTLIST}) INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/${PQ}.so") ENDFOREACH (PQ) # PyQwt IF (@OSX_HAVE_LOADERPATH@) SET (QFW_CHG_TO "${ATLOADER}/../../../@QGIS_DATA_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}") ENDIF () FOREACH (PW _iqt;Qwt) IF (EXISTS "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so") INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QGISPYDIR}/PyQt${QT_FWVER}/Qwt5/${PW}.so") ENDIF () ENDFOREACH (PW) # bin - PyQt utils SET (QFW_CHG_TO "${ATEXECUTABLE}/@QGIS_BIN_SUBDIR_REV@/${QGIS_FW_SUBDIR}/${LIBPOST}") FOREACH (PB pylupdate4;pyrcc4) INSTALLNAMETOOL_CHANGE ("${QFW_CHG}" "${QFW_CHG_TO}" "${QBINDIR}/${PB}") ENDFOREACH (PB) ENDFOREACH (QFW)