# CMake/packaging/mac/MacPackagingTasks.cmake.in

# CMake/packaging/mac/MacPackagingTasks.cmake.in |
--- | ---
¶ OS X packaging tasks |
¶ This file is processed by `CONFIGURE_FILE` in `../CMakeLists.txt` which inserts values for `@VARIABLE@` declarations. This is done to import values for some variables that would otherwise be undefined when CPack is running. |
    SET(PROJECT_NAME @PROJECT_NAME@)
    SET(PROJECT_SOURCE_DIR @PROJECT_SOURCE_DIR@)
    SET(PROJECT_BINARY_DIR @PROJECT_BINARY_DIR@)
    SET(TeXworks_LIB_DIRS @TeXworks_LIB_DIRS@)
    SET(CMAKE_SHARED_LIBRARY_SUFFIX @CMAKE_SHARED_LIBRARY_SUFFIX@)
    SET(QT_PLUGINS @QT_PLUGINS@)
¶ This `IF` statement ensures that the following commands are executed only when CPack is running---i.e. when a user executes `make package` but not `make install` |
    IF ( ${CMAKE_INSTALL_PREFIX} MATCHES .*/_CPack_Packages/.* )
¶ ## Download and install Poppler data |
      IF ( NOT EXISTS ${PROJECT_SOURCE_DIR}/poppler-data-0.4.4.tar.gz )
        MESSAGE(STATUS "Downloading Poppler data files")
        FILE(DOWNLOAD "http://poppler.freedesktop.org/poppler-data-0.4.5.tar.gz"
          ${PROJECT_SOURCE_DIR}/poppler-data-0.4.5.tar.gz
          EXPECTED_MD5 448dd7c5077570e340340706cef931aa
          SHOW_PROGRESS
        )
      ENDIF ()

      IF ( NOT EXISTS ${PROJECT_SOURCE_DIR}/poppler-data-0.4.5 )
        EXECUTE_PROCESS(COMMAND tar xzf ${PROJECT_SOURCE_DIR}/poppler-data-0.4.5.tar.gz
          WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
        )
      ENDIF ()

      FILE(INSTALL ${PROJECT_SOURCE_DIR}/poppler-data-0.4.5/
        DESTINATION ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app/Contents/poppler-data
        PATTERN CMakeLists.txt EXCLUDE
        PATTERN Makefile EXCLUDE
      )
¶ ## Download and install TeXworks manual |
      IF ( NOT EXISTS ${PROJECT_SOURCE_DIR}/TeXworks-manual-html-r959.zip )
        MESSAGE(STATUS "Downloading TeXworks HTML manual")
        FILE(DOWNLOAD
          "http://texworks.googlecode.com/files/TeXworks-manual-html-r959.zip"
          ${PROJECT_SOURCE_DIR}/TeXworks-manual-html-r959.zip
          EXPECTED_MD5 2071e3c2fc6b6fdb57bca0484abdd35a
          SHOW_PROGRESS
        )
      ENDIF ()

      IF ( NOT EXISTS ${PROJECT_SOURCE_DIR}/TeXworks-manual )
        EXECUTE_PROCESS(COMMAND unzip ${PROJECT_SOURCE_DIR}/TeXworks-manual-html-r959.zip
          WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
        )
      ENDIF ()

      FILE(INSTALL ${PROJECT_SOURCE_DIR}/TeXworks-manual
        DESTINATION ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app/Contents/texworks-help/
      )
¶ ## Copy all runtime dependencies and rewrite loader paths |
¶ Bring in `DeployQt4` a CMake module taken from the Charm application: https://github.com/KDAB/Charm This module offers the `FIXUP_QT4_BUNDLE` function which wraps `FIXUP_BUNDLE` from CMake's `BundleUtilities` module and extends it with additional Qt4-specific goodies---such as installing Qt4 plugins. `FIXUP_BUNDLE` is a wonderful function that examines an executable, finds all non-system libraries it depends on, copies them into the `.app` bundle and then re-writes the necessary loader paths. |
      SET(CMAKE_MODULE_PATH @CMAKE_MODULE_PATH@)
      INCLUDE(DeployQt4)
¶ Gather all TeXworks Plugin libraries. |
      FILE(GLOB TeXworks_PLUGINS
        ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app/Contents/PlugIns/*${CMAKE_SHARED_MODULE_SUFFIX})
¶ If `BU_CHMOD_BUNDLE_ITEMS` is not set, `install_name_tool` will fail to re-write some loader paths due to insufficiant permissions. |
      SET(BU_CHMOD_BUNDLE_ITEMS ON)

      FIXUP_QT4_BUNDLE(${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app "${QT_PLUGINS}" "${TeXworks_PLUGINS}" "${TeXworks_LIB_DIRS}")
¶ ## Remove unecessary architectures from universal binaries |
¶ Some libraries copied from the OS X system, such as X11 libraries, may contain up to 4 different architectures. Here we will iterate over these libraries and use `lipo` to strip out un-needed architectures. |
¶ Another useful function from `BundleUtilities`. |
      GET_BUNDLE_MAIN_EXECUTABLE(${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app APP_MAIN)
¶ We look at the TeXworks binary that was built rather than consulting the value of the `CMAKE_OSX_ARCHITECTURES` because if the user did not set `CMAKE_OSX_ARCHITECTURES`, then the variable will be an empty string and the format of the resulting binary will depend on the versions of OS X and XCode. |
      MESSAGE(STATUS "Reducing the size of bundled libraries.")
      MESSAGE(STATUS "Scanning architectures of: ${APP_MAIN}")
      EXECUTE_PROCESS(
¶ `lipo -info` returns a list of the form:
    <is universal binary?>: <program name>: <list of architectures>
Piping this output to `cut -d : -f 3-` allows us to extract just the list of architectures. |
        COMMAND lipo -info ${APP_MAIN}
        COMMAND cut -d : -f 3-
        OUTPUT_VARIABLE APP_ARCHS
      )
¶ Strip leading and trailing whitespace. |
      STRING(STRIP ${APP_ARCHS} APP_ARCHS)
¶ Convert spaces to semicolons so CMake will interpret the string as a list. |
      STRING(REPLACE " " ";" APP_ARCHS ${APP_ARCHS})

      MESSAGE(STATUS "Will reduce bundled libraries to: ${APP_ARCHS}")

      FOREACH(ARCH IN LISTS APP_ARCHS)
        SET(ARCHS_TO_EXTRACT "${ARCHS_TO_EXTRACT} -extract ${ARCH}")
      ENDFOREACH ()
¶ NOTE: This will not process any dylibs from Frameworks copied by `FIXUP_BUNDLE`, hence it may not touch any of the Qt libraries. Something to fix in the future. |
      FILE(GLOB BUNDLED_DYLIBS
        ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app/Contents/MacOS/*${CMAKE_SHARED_LIBRARY_SUFFIX})

      FOREACH(DYLIB IN LISTS BUNDLED_DYLIBS)
        MESSAGE(STATUS "Processing included library: ${DYLIB}")
¶ `lipo` is very very anal about how arguments get passed to it. So we execute through bash to side-step the issue. |
        EXECUTE_PROCESS(COMMAND bash -c "lipo ${ARCHS_TO_EXTRACT} ${DYLIB} -output ${DYLIB}")
      ENDFOREACH ()

      MESSAGE(STATUS "Finished stripping architectures from bundled libraries.")

    ENDIF ()