Files
quarrel07 aa6c9c10ca macOS: package the game as a proper SpaghettiKart.app bundle (#724)
* macOS: package the game as a proper SpaghettiKart.app bundle

Turns the bare Spaghettify executable into a self-contained SpaghettiKart.app:

- cmake/macos/apple_bundle.cmake: bundle metadata (using the existing
  Info.plist, which already described a bundle), app icon, runtime resources
  (config.yml, yamls, meta, spaghetti.o2r) into Contents/Resources, dylib
  relinking for local Homebrew builds (no-op with static vcpkg deps), and
  ad-hoc codesigning so the app launches without 'damaged app' warnings
- App icon: on Xcode 26+ the Icon Composer package (SpaghettiKartIcon.icon,
  drawn from the existing HM ship-kart icon.png art) compiles with actool
  into an Assets.car, giving the native Liquid Glass look on macOS 26+, plus
  a flattened icns for older systems; older Xcode falls back to the previous
  sips/iconutil flat icon. Supersedes the CreateOSXIcons target.
- Game.cpp: default SHIP_HOME to ~/Library/Application Support/SpaghettiKart
  on macOS so first-run extraction, saves, config, and mods land there
  instead of scattering into the user's home folder; a user-set SHIP_HOME
  still wins
- Info.plist: NSHighResolutionCapable for proper Retina rendering
- CI: mac jobs now ship the .app (ditto zip so the executable bit survives
  artifact upload)
- the yamls-next-to-exe copy is scoped to non-Darwin; on macOS those files
  live in Contents/Resources instead

* macOS: ship prebuilt icon artifacts instead of compiling them at build time

Commits the compiled Assets.car (Liquid Glass icon for macOS 26+) and the
flattened SpaghettiKart.icns, both built from the in-repo Icon Composer
package. The build now just copies them into the bundle, which removes the
actool machinery and the Xcode 26 requirement entirely: every build on any
machine, including CI, gets the real icon.

Also adds a staleness guard: the artifacts carry a hash stamp of the
icon.png they were made from, and if icon.png ever changes without them
being regenerated, the build automatically generates a flat icns from the
current icon.png instead, so updating the logo never requires any macOS
work and an outdated icon can never ship. Regeneration steps are documented
in apple_bundle.cmake.

* Rename the icon layer to ship-kart-layer.png

Group 2.png was the design tool's default layer name; name it for what it
is. Verified the Icon Composer package still compiles with actool after the
rename; the committed Assets.car is unaffected (compiled, self-contained).

---------

Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
2026-08-01 19:35:51 -06:00

32 lines
1.1 KiB
CMake

# Run at build time (cmake -P) to copy non-system dylibs the executable links
# against into the .app's Contents/Frameworks and rewrite the load paths, making
# the bundle self-contained / portable. Invoked from apple_bundle.cmake.
#
# Expects -D APP_BUNDLE=<abs path to SpaghettiKart.app> -D EXECUTABLE_NAME=SpaghettiKart
include(BundleUtilities)
set(APP "${APP_BUNDLE}/Contents/MacOS/${EXECUTABLE_NAME}")
file(REAL_PATH "${APP}" APP)
# Where fixup_bundle should look for the dependencies it needs to copy in.
set(SEARCH_DIRS
"/opt/homebrew/lib" # Homebrew (Apple Silicon)
"/usr/local/lib" # Homebrew (Intel) / misc
"/opt/local/lib" # MacPorts
"${APP_BUNDLE}/Contents/Frameworks"
)
set(RESOLVED_DIRS "")
foreach(DIR IN LISTS SEARCH_DIRS)
if (EXISTS "${DIR}")
file(REAL_PATH "${DIR}" RESOLVED_DIR)
list(APPEND RESOLVED_DIRS "${RESOLVED_DIR}")
endif()
endforeach()
message(STATUS "fixup_bundle: ${APP}")
message(STATUS "fixup_bundle search dirs: ${RESOLVED_DIRS}")
fixup_bundle("${APP}" "" "${RESOLVED_DIRS}")