macOS: fix launch crash, missing dylibs, and dmg volume icon

The app crashed at launch with "cannot be opened because of a
problem" because macdeployqt invalidates the code signature when it
rewrites library load paths; re-sign (ad hoc) after macdeployqt runs.

Also fixes the underlying cause of a Library-missing crash: orbithub's
INSTALL_RPATH used the Linux linker token $ORIGIN, which dyld does not
understand, and the bundled FreeRDP/WinPR/KodoTerm dylibs installed to
a sibling lib/orbithub/ directory outside OrbitHub.app rather than
Contents/Frameworks, so they were never copied into the dmg at all.
Both are now APPLE-specific, matching macdeployqt's own layout
(Contents/Frameworks, @executable_path/../Frameworks).

build-dmg.sh now also sets a custom volume icon (via SetFile or the
fileicon brew formula, whichever is available) instead of the
generic disk image icon, degrading gracefully if neither is present.

Also includes the StartupWMClass desktop-file fix from the prior
commit's message, which was never actually staged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-08 14:00:46 -06:00
co-authored by Claude Sonnet 5
parent 3840ea9f62
commit aa812b0da7
3 changed files with 73 additions and 8 deletions
+21 -6
View File
@@ -202,18 +202,33 @@ if(WIN32)
endif() endif()
endif() endif()
set_target_properties(orbithub PROPERTIES if(APPLE)
BUILD_RPATH_USE_ORIGIN ON # Mirrors macdeployqt's own layout for Qt frameworks: dylibs live in
INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/orbithub" # Contents/Frameworks inside the bundle, found via @executable_path
INSTALL_RPATH_USE_LINK_PATH ON # (the macOS/dyld equivalent of Linux's $ORIGIN token, which dyld
) # does not understand).
set_target_properties(orbithub PROPERTIES
INSTALL_RPATH "@executable_path/../Frameworks"
INSTALL_RPATH_USE_LINK_PATH ON
)
else()
set_target_properties(orbithub PROPERTIES
BUILD_RPATH_USE_ORIGIN ON
INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/orbithub"
INSTALL_RPATH_USE_LINK_PATH ON
)
endif()
install(TARGETS orbithub install(TARGETS orbithub
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION . BUNDLE DESTINATION .
) )
set(ORBITHUB_PRIVATE_LIB_DESTINATION "${CMAKE_INSTALL_LIBDIR}/orbithub") if(APPLE)
set(ORBITHUB_PRIVATE_LIB_DESTINATION "OrbitHub.app/Contents/Frameworks")
else()
set(ORBITHUB_PRIVATE_LIB_DESTINATION "${CMAKE_INSTALL_LIBDIR}/orbithub")
endif()
set(ORBITHUB_RUNTIME_TARGETS KodoTerm freerdp winpr) set(ORBITHUB_RUNTIME_TARGETS KodoTerm freerdp winpr)
if(TARGET freerdp-client) if(TARGET freerdp-client)
list(APPEND ORBITHUB_RUNTIME_TARGETS freerdp-client) list(APPEND ORBITHUB_RUNTIME_TARGETS freerdp-client)
@@ -7,5 +7,6 @@ Comment=Manage SSH and RDP sessions in one native app
Exec=orbithub Exec=orbithub
Icon=org.darksingularity.OrbitHub Icon=org.darksingularity.OrbitHub
Terminal=false Terminal=false
StartupWMClass=OrbitHub
Categories=Network;RemoteAccess;Utility; Categories=Network;RemoteAccess;Utility;
StartupNotify=true StartupNotify=true
+51 -2
View File
@@ -41,11 +41,60 @@ fi
"$MACDEPLOYQT" "$INSTALL_PREFIX/$APP_BUNDLE" "$MACDEPLOYQT" "$INSTALL_PREFIX/$APP_BUNDLE"
# macdeployqt rewrites library load paths after bundling Qt, which
# invalidates any prior signature. Re-sign (ad hoc, since we have no
# Developer ID certificate) so the app passes macOS's code-integrity
# check at launch. Without this, launching fails with a generic
# "cannot be opened because of a problem" crash-reporter dialog rather
# than the milder unidentified-developer Gatekeeper prompt.
codesign --force --deep --sign - "$INSTALL_PREFIX/$APP_BUNDLE"
cp -R "$INSTALL_PREFIX/$APP_BUNDLE" "$STAGE_DIR/$APP_BUNDLE" cp -R "$INSTALL_PREFIX/$APP_BUNDLE" "$STAGE_DIR/$APP_BUNDLE"
ln -s /Applications "$STAGE_DIR/Applications" ln -s /Applications "$STAGE_DIR/Applications"
cp "$ROOT_DIR/packaging/macos/orbithub.icns" "$STAGE_DIR/.VolumeIcon.icns"
OUTPUT_DMG="$DIST_DIR/OrbitHub-${VERSION}.dmg" OUTPUT_DMG="$DIST_DIR/OrbitHub-${VERSION}.dmg"
rm -f "$OUTPUT_DMG" RW_DMG="$DIST_DIR/OrbitHub-rw.dmg"
hdiutil create -volname "OrbitHub" -srcfolder "$STAGE_DIR" -ov -format UDZO "$OUTPUT_DMG" rm -f "$OUTPUT_DMG" "$RW_DMG"
hdiutil create -volname "OrbitHub" -srcfolder "$STAGE_DIR" -ov -format UDRW "$RW_DMG"
# Setting the volume's icon requires flipping a Finder attribute bit,
# which needs SetFile (from Xcode's "Additional Tools", not the base
# Command Line Tools) or the fileicon brew formula. Neither is
# guaranteed to be installed, so this step degrades gracefully: the
# dmg is still produced either way, just without a custom icon if no
# tool is available.
ICON_TOOL=""
if command -v SetFile >/dev/null 2>&1; then
ICON_TOOL="SetFile"
elif [[ -x /Library/Developer/CommandLineTools/usr/bin/SetFile ]]; then
ICON_TOOL="/Library/Developer/CommandLineTools/usr/bin/SetFile"
elif command -v fileicon >/dev/null 2>&1; then
ICON_TOOL="fileicon"
fi
if [[ -n "$ICON_TOOL" ]]; then
MOUNT_DIR="$(mktemp -d)"
hdiutil attach "$RW_DMG" -mountpoint "$MOUNT_DIR" -nobrowse -quiet
if [[ "$ICON_TOOL" == "fileicon" ]]; then
fileicon set "$MOUNT_DIR" "$ROOT_DIR/packaging/macos/orbithub.icns" >/dev/null
else
"$ICON_TOOL" -a V "$MOUNT_DIR/.VolumeIcon.icns"
"$ICON_TOOL" -a C "$MOUNT_DIR"
fi
hdiutil detach "$MOUNT_DIR" -quiet
rmdir "$MOUNT_DIR" 2>/dev/null || true
else
echo "Note: SetFile/fileicon not found, dmg will use the generic disk icon." >&2
echo " Install one to get a custom volume icon:" >&2
echo " brew install fileicon" >&2
echo " or download 'Additional Tools for Xcode' from developer.apple.com/download/all" >&2
fi
hdiutil convert "$RW_DMG" -format UDZO -ov -o "$OUTPUT_DMG"
rm -f "$RW_DMG"
echo "Created $OUTPUT_DMG" echo "Created $OUTPUT_DMG"