1include(BundleUtilities) 2 3# After the relevant targets, support files, as well as plugins have already been installed into the bundle structure, 4# the bundle must still be made standalone by copying the required frameworks and making them position-independent. 5# This is generally called "fixing up" the bundle. 6# 7# Principally there are two ways to do that: Qt's official macdeployqt tool, and CMake's BundleUtilities. 8# 9# Some frameworks, in particular QtWebEngineCore, come with nested bundles. In order for them to work correctly, the Frameworks directory 10# from the main bundle must be symlinked into the nested bundle, otherwise dependencies cannot be resolved. 11# Neither macdeployqt (shockingly) nor BundleUtilities can handle this properly. The former simply ignores nested bundles and thus 12# does not fix them up at all. The latter scans for additional binaries and tries fixing them up, but there is no way to inject 13# creation of the Frameworks symlink between the copy and the fixup steps. 14# 15# The working solution implemented here is to first run macdeployqt (which also handles some Qt-specific quirks), then symlink Frameworks 16# into the nested bundles (if any), then use BundleUtilities to perform the remaining fixups and verify the bundle. 17 18# Since we're in the install phase, DESTDIR might be set 19set(BUNDLE_PATH "$ENV{DESTDIR}@BUNDLE_PATH@") 20set(DMG_PATH "$ENV{DESTDIR}@DMG_PATH@") 21 22# First, use Qt's official tool, macdeployqt, for deploying the needed Qt Frameworks into the bundle 23message(STATUS "Deploying Qt Frameworks in bundle \"${BUNDLE_PATH}\"") 24execute_process( 25 # Don't deploy plugins - we've already installed the selection relevant for our target! 26 COMMAND @MACDEPLOYQT_EXECUTABLE@ "${BUNDLE_PATH}" -verbose=1 -no-plugins 27 RESULT_VARIABLE result 28) 29if(NOT result EQUAL 0) 30 message(FATAL_ERROR "Deploying Qt Frameworks failed.") 31endif() 32 33# Scan for nested bundles and symlink the main bundle's Frameworks directory into them 34message(STATUS "Checking for nested bundles") 35execute_process( 36 COMMAND find "${BUNDLE_PATH}" -mindepth 1 -type d -name "*.app" 37 OUTPUT_VARIABLE nested_bundles 38 OUTPUT_STRIP_TRAILING_WHITESPACE 39) 40if(nested_bundles) 41 string(REPLACE "\n" ";" nested_bundles ${nested_bundles}) 42 foreach(nested_bundle IN LISTS nested_bundles) 43 message(STATUS "Symlinking Frameworks into nested bundle \"${nested_bundle}\"") 44 file(RELATIVE_PATH path "${nested_bundle}/Contents" "${BUNDLE_PATH}/Contents/Frameworks") 45 execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${path}" "${nested_bundle}/Contents/Frameworks") 46 endforeach() 47else() 48 message("Checking for nested bundles - none found") 49endif() 50 51# Now fixup the whole thing using CMake's own tooling, which (unlike macdeployqt) will take care of any additional internal executables 52message(STATUS "Fixing up bundle...") 53fixup_bundle("${BUNDLE_PATH}" "" "") 54 55# Create the DMG image 56message(STATUS "Creating DMG image...") 57execute_process( 58 COMMAND hdiutil create "${DMG_PATH}" -srcfolder "${BUNDLE_PATH}" -format "UDBZ" -fs "HFS+" -volname "Quassel IRC" 59 RESULT_VARIABLE result 60) 61if(NOT result EQUAL 0) 62 message(FATAL_ERROR "Creating DMG image failed.") 63endif() 64