Merge pull request #40 from digarok/ci/macos-universal-and-deployment-target

CI: add universal macOS build + fix minimum-OS deployment target
This commit is contained in:
Dagen Brock authored and GitHub committed 2026-06-28 17:34:12 -05:00
commit ecefb04e2b
2 files changed
+64 -6

No files matched your search

+37 -1
View File
@@ -37,6 +37,42 @@ jobs:
name: gsplus-macos
path: build/*.dmg
macos-universal:
# Second macOS build producing a UNIVERSAL (arm64 + x86_64) app, alongside
# the arm64-only `macos` job above. Key difference: we do NOT install
# Homebrew's SDL3 (it ships a single-arch arm64 dylib you can't link into a
# universal binary). With no system SDL3, CMake's FetchContent path builds
# SDL3 from source, and CMAKE_OSX_ARCHITECTURES makes that build -- and ours
# -- universal. fixup_bundle then embeds the universal SDL3 into the .app.
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install tools
# NB: intentionally no `sdl3` here -- see the comment above.
run: brew install cmake ninja
- name: Configure (universal, SDL3 built from source)
run: |
ARGS=""
case "$GITHUB_REF" in
refs/tags/v*) ARGS="-DGSPLUS_VERSION=${GITHUB_REF_NAME#v}" ;;
esac
cmake -G Ninja -B build -S gsplus/src \
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" $ARGS
- name: Build
run: cmake --build build --target gsplus-sdl
- name: Package (.dmg) and label universal
run: |
cd build && cpack
# CPack names it GSplus-<ver>-Darwin.dmg; rename so it doesn't collide
# with the arm64-only dmg when both attach to the same Release.
for f in GSplus-*-Darwin.dmg; do
mv "$f" "${f/-Darwin.dmg/-macOS-universal.dmg}"
done
- uses: actions/upload-artifact@v4
with:
name: gsplus-macos-universal
path: build/*.dmg
linux:
runs-on: ubuntu-latest
steps:
@@ -105,7 +141,7 @@ jobs:
release:
if: startsWith(github.ref, 'refs/tags/')
needs: [ macos, linux, windows ]
needs: [ macos, macos-universal, linux, windows ]
runs-on: ubuntu-latest
permissions:
contents: write # required for the token to create a Release
+27 -5
View File
@@ -149,7 +149,18 @@ message(STATUS "GSplus: configured core library (build type: ${CMAKE_BUILD_TYPE}
# Swift runtime linking / rpaths automatically, which is the fragile part the
# Makefile does by hand.
# ----------------------------------------------------------------------------
if(APPLE)
# CMake's Swift support can't build a universal (multi-arch) binary -- it errors
# with "multiple values for CMAKE_OSX_ARCHITECTURES not supported with Swift".
# The native Cocoa app is legacy/secondary and excluded from the default build,
# so when a universal build is requested (the CI macos-universal job passes
# arm64;x86_64) we simply skip it; the shipped SDL app (gsplus-sdl, plain C) has
# no such restriction and still builds universal.
list(LENGTH CMAKE_OSX_ARCHITECTURES _gsplus_narch)
if(APPLE AND _gsplus_narch GREATER 1)
message(STATUS "GSplus: universal build -- skipping the Swift Cocoa app (Swift can't do multi-arch)")
endif()
if(APPLE AND _gsplus_narch LESS 2)
# Turn on CMake's Swift language support. This makes CMake able to compile
# .swift files and, when it links a target that contains Swift, pull in the
# Swift runtime and set rpaths for us.
@@ -258,6 +269,11 @@ target_link_libraries(gsplus-sdl PRIVATE gsplus_core_sdl SDL3::SDL3)
if(APPLE)
# macOS-only: retune SDL's default menu bar so ⌘ combos pass through to the
# emulated IIgs and GSplus quits on ⌥⌘Q. The Objective-C source needs Cocoa.
# Explicitly enable the OBJC language so CMake has a proper compile rule for
# the .m file. A single-arch build tolerates compiling it via the C rule, but
# a universal build (CMAKE_OSX_ARCHITECTURES=arm64;x86_64) errors with
# "CMAKE_OBJC_COMPILE_OBJECT not set" unless OBJC is enabled.
enable_language(OBJC)
target_sources(gsplus-sdl PRIVATE sdl_mac_menu.m)
target_link_libraries(gsplus-sdl PRIVATE "-framework Cocoa")
endif()
@@ -346,12 +362,18 @@ if(APPLE)
# bundle. We then re-sign ad-hoc ("-"): editing a binary invalidates its
# code signature, and arm64 macOS refuses to launch a broken-signature app.
install(TARGETS gsplus-sdl BUNDLE DESTINATION .)
install(CODE [[
# Tell fixup_bundle which directory to search for @rpath-named dylibs. A
# Homebrew SDL3 records an absolute/resolvable install name, but a
# FetchContent-built SDL3 (the universal job, and any host without system
# SDL3) names itself @rpath/libSDL3.0.dylib -- fixup_bundle can't find that
# unless we hand it the directory containing the built dylib. The genex
# resolves to Homebrew's libdir or the FetchContent build dir as appropriate.
install(CODE "
include(BundleUtilities)
fixup_bundle("${CMAKE_INSTALL_PREFIX}/GSplus.app" "" "")
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/GSplus.app\" \"\" \"$<TARGET_FILE_DIR:SDL3::SDL3>\")
execute_process(COMMAND codesign --force --deep --sign -
"${CMAKE_INSTALL_PREFIX}/GSplus.app")
]])
\"\${CMAKE_INSTALL_PREFIX}/GSplus.app\")
")
set(CPACK_GENERATOR "DragNDrop") # -> a .dmg
set(CPACK_DMG_VOLUME_NAME "GSplus")
else()