Getting macdeployqt to handle multiple binaries in the bundle
-
I build a Command Line version of DeepSkyStacker called DeepSkyStackerCL in its own directory as a loose binary (i.e. not in a bundle). I, when I build DeepSkyStacker, I copy it into the bundle at the end of the build:
if(APPLE) add_custom_command(TARGET DeepSkyStacker POST_BUILD # # Now we've built the DSS .app bundle, copy the DSSCL binary into the bundle # The use of $<TARGET_FILE:DeepSkyStackerCL> in add_custom_command also adds # a dependency on the target, so that the DSSCL binary is built before this. # COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:DeepSkyStackerCL> $<TARGET_BUNDLE_CONTENT_DIR:DeepSkyStacker>/MacOS/ COMMAND "$ENV{HOME}/.unlock_keychain" ) endif() if(NOT LINUX) set (deploy_tool_options_arg "-verbose=1") if(APPLE) set(deploy_tool_options_arg "${deploy_tool_options_arg} -hardened-runtime -timestamp -no-strip") set(deploy_tool_options_arg "${deploy_tool_options_arg} \"-codesign=Developer ID Application: David Partridge (VH8AYT3C7Y)\"") elseif(WIN32) set(deploy_tool_options_arg "${deploy_tool_options_arg} --pdb") endif() # Generate a deployment script to be executed at install time # App bundles on macOS have an .app suffix if(APPLE) set(executable_path "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:DeepSkyStacker>.app") else() message ("Target filename:" $<TARGET_FILE_NAME:DeepSkyStacker>) set(executable_path "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:DeepSkyStacker>") endif() message ("executable_path: " ${executable_path}) message ("deploy tools options arg: " ${deploy_tool_options_arg}) qt_generate_deploy_script( TARGET DeepSkyStacker OUTPUT_SCRIPT deploy_script CONTENT " qt_deploy_runtime_dependencies( EXECUTABLE \"${executable_path}\" DEPLOY_TOOL_OPTIONS ${deploy_tool_options_arg} )" ) else() qt_generate_deploy_app_script( TARGET ${PROJECT_NAME} OUTPUT_SCRIPT deploy_script DEPLOY_TOOL_OPTIONS ${deploy_tool_options_arg} ) endif() install (SCRIPT ${deploy_script}) install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION .)
Which is fine except that DeepSkyStackerCL doesn't get updated to point to the libraries in the bundle, so when I try to run it I get:
amonra@Saturn Debug % DSSCL dyld[54749]: Library not loaded: @rpath/QtWidgets.framework/Versions/A/QtWidgets Referenced from: <6DE065A6-9F76-3296-9667-682886AB7282> /Applications/DeepSkyStacker.app/Contents/MacOS/DeepSkyStackerCL Reason: tried: '/usr/local/lib/QtWidgets.framework/Versions/A/QtWidgets' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/QtWidgets.framework/Versions/A/QtWidgets' (no such file), '/opt/Qt/6.8.2/macos/lib/QtWidgets.framework/Versions/A/QtWidgets' (code signature in <B16538D5-4C8E-357D-B89A-72F6F81A918D> '/opt/Qt/6.8.2/macos/lib/QtWidgets.framework/Versions/A/QtWidgets' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/System/Volumes/Preboot/Cryptexes/OS/opt/Qt/6.8.2/macos/lib/QtWidgets.framework/Versions/A/QtWidgets' (no such file), '/usr/local/lib/QtWidgets.framework/Versions/A/QtWidgets' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/lib/QtWidgets.framework/Versions/A/QtWidgets' (no such file), '/opt/Qt/6.8.2/macos/lib/QtWidgets.framework/Versions/A/QtWidgets' (code signature in <B16538D5-4C8E-357D-B89A-72F6F81A918D> '/opt/Qt/6.8.2/macos/lib/QtWidgets.framework/Versions/A/QtWidgets' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/System/Volumes/Preboot/Cryptexes/OS/opt/Qt/6.8.2/macos/lib/QtWidgets.framework/Versions/A/QtWidgets' (no such file) zsh: abort DSSCL
How can I persuade macdeployqt to process all the binaries in the Contents/MacOS directory of the bundle?
Is it as simple as adding:
set(deploy_tool_options_arg "${deploy_tool_options_arg} \"-executable=$<TARGET_BUNDLE_CONTENT_DIR:DeepSkyStacker>/MacOS/DeepSkyStackerCL\"")
to the above code?
Thanks
David -
Hi @Perdrix,
The
qt_deploy_runtime_dependencies()
command has anADDITIONAL_EXECUTABLES
parameter that likely does what you're after?Cheers.
-
Hi @Perdrix,
I should stop using macdeployqt and windeployqt and use
qt_deploy_runtime_dependencies
in all cases?If I'm reading your original post correctly, it looks like you're already using
qt_deploy_runtime_dependencies()
for both macOS and Windows.You can use
macdeployqt
andwindeployqt
directly, butqt_deploy_runtime_dependencies()
wraps them for you. From the docs:... when executed on macOS or Windows, the command will use either
macdeployqt
orwindeployqt
, ...If that's now the official position I'll go with it.
I'm not sure either is considered "the official position" - both seem to be supported, and in my mind, both are good options. Though
qt_deploy_runtime_dependencies()
was only added in Qt 6.3, so if you want to support older Qt's, then executing{mac,win}deployqt
directly is the way to go, otherwise I'd stick withqt_deploy_runtime_dependencies()
if/while it meets your needs.Either way,
- if you stick with
qt_deploy_runtime_dependencies()
, then try adding anADDITIONAL_EXECUTABLES
parameter; or - if you want to use
{mac,win}deployqt
directly, then just copy all of your executables to a staging area, and run{mac,win}deployqt
on all of them.
Cheers.
- if you stick with