diff --git a/CMakeLists.txt b/CMakeLists.txt index 994cfeb..111ea69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,18 +202,33 @@ if(WIN32) endif() endif() -set_target_properties(orbithub PROPERTIES - BUILD_RPATH_USE_ORIGIN ON - INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}/orbithub" - INSTALL_RPATH_USE_LINK_PATH ON -) +if(APPLE) + # Mirrors macdeployqt's own layout for Qt frameworks: dylibs live in + # Contents/Frameworks inside the bundle, found via @executable_path + # (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 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 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) if(TARGET freerdp-client) list(APPEND ORBITHUB_RUNTIME_TARGETS freerdp-client) diff --git a/packaging/linux/org.darksingularity.OrbitHub.desktop b/packaging/linux/org.darksingularity.OrbitHub.desktop index b7a88fd..4e35a26 100644 --- a/packaging/linux/org.darksingularity.OrbitHub.desktop +++ b/packaging/linux/org.darksingularity.OrbitHub.desktop @@ -7,5 +7,6 @@ Comment=Manage SSH and RDP sessions in one native app Exec=orbithub Icon=org.darksingularity.OrbitHub Terminal=false +StartupWMClass=OrbitHub Categories=Network;RemoteAccess;Utility; StartupNotify=true diff --git a/packaging/macos/build-dmg.sh b/packaging/macos/build-dmg.sh index 9857ef2..ad7965d 100755 --- a/packaging/macos/build-dmg.sh +++ b/packaging/macos/build-dmg.sh @@ -41,11 +41,60 @@ fi "$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" ln -s /Applications "$STAGE_DIR/Applications" +cp "$ROOT_DIR/packaging/macos/orbithub.icns" "$STAGE_DIR/.VolumeIcon.icns" OUTPUT_DMG="$DIST_DIR/OrbitHub-${VERSION}.dmg" -rm -f "$OUTPUT_DMG" -hdiutil create -volname "OrbitHub" -srcfolder "$STAGE_DIR" -ov -format UDZO "$OUTPUT_DMG" +RW_DMG="$DIST_DIR/OrbitHub-rw.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"