Repository navigation
Conversation
The macOS build uses Apple Foundation and the existing SDL3 front end instead of GNUstep: - Meson: a darwin branch (src/meson/darwin), a darwin.ini native file that mk.sh selects on macOS, and the Info plist embedded in the binary. - SpiderMonkey: ShellScripts/macOS/build_mozilla_js.sh builds an interpreter-only arm64 library from source with three small patches. - OOFoundation.h: Apple Foundation with OOLITE_SDL; OOLITE_MAC_COCOA_UI marks code for the removed Cocoa front end. - OpenGL: macOS only offers a legacy 2.1 context, so the version gate accepts it with the required extensions, VAOs map to the APPLE extension, MSAA uses a renderbuffer, and the #version 330 post-processing shaders are translated to GLSL 1.20 when loaded. - Packaging: post_build.sh creates a self-contained, ad-hoc signed oolite.app (Homebrew dylibs in Contents/Frameworks), install copies it to /Applications, and ./mk.sh pkg-dmg builds a drag-to-install DMG. - CI: macOS jobs in both workflows; the release attaches the DMGs. Fixes in shared code found along the way: - Save the window size in points and scale mouse coordinates by the pixel density (window grew each launch, clicks were misplaced on high-DPI displays). - Don't create an SDL window surface on the GL window on macOS. - Read the debug console socket only while data is available on macOS (Apple streams block, freezing the game loop). - addShipToShipyard inserted nil when no personality was given. - Shader switch statements and an interface block replaced with equivalent GLSL that also works in 1.20.
NSHost does blocking DNS lookups, and on GitHub's macOS runners the game hung while connecting to the snapshot test's console. Use CFStreamCreatePairWithSocketToHost with the address instead. The test launcher now samples the process on macOS if it fails to connect.
CFNetwork's host-based stream connection stalled for around 18 seconds on GitHub's macOS runners, close to the snapshot test's timeout. Connect a socket directly (non-blocking, 3 second timeout) and wrap it in streams.
|
@hobleyd Thanks for this PR which makes it easier to see what is changed than the other ones. Have you run the game locally loading a few OXPs to see how well it works on Mac? I tested the appimage briefly on Linux and it seems fine so nothing appears to be broken. Rather than trying to get an old version of OpenGL working (which might lead to a suboptimal Mac experience?), I think it would be preferable to switch to SDL_GPU for all platforms: #579 (or failing that Vulkan which also has a Metal backend). Given the age of the JS engine, it would be great to investigate QuickJS-NG as a JS engine replacement for all platforms: see #580. If you're prepared to use your AI, you might be able to build on your working Mac setup and check if this library (or any other lightweight cross platform JavaScript library) can easily be used a substitute. I had planned to look into those things first, but your PR is in a pretty good state so it's probably better to start with it first. @phkb What do you think? |
|
I have run it briefly locally, not with loading OXPs yet - will test that next. I can also look at both of those issues.... I'll raise some more PRs... |
Summary
This makes Oolite build and run natively on Apple Silicon Macs, using Apple Foundation with the existing Meson + SDL3 front end instead of GNUstep. Each build type produces a self-contained
oolite.appand a drag-to-install DMG. CI builds all three build types on macOS, runs the snapshot smoke test, and attaches the DMGs to the prerelease.Build steps on a Mac (also in the README):
Changes
Build system
src/meson/darwin/meson.buildand adarwin.ininative file (Apple clang and ld64, since Apple's toolchain has no lld).mk.shpicks the native file automatically on macOS, and re-runs itself under Homebrew bash 4+.[[NSBundle mainBundle] infoDictionary]works on Apple Foundation; the GNUstep build usesNSBundle+Overridefor this.get_version.sh,get_build_date_fn.shandpost_build.shwork with macOS tools: the meson parent-process check, GNUdate/cpfrom coreutils, and the padded output of BSDwc.SpiderMonkey
ShellScripts/macOS/build_mozilla_js.shbuilds the samemozillajs-linuxsource (pinned commit) for arm64 without the old configure step, which needs Python 2. It builds the interpreter only, because the tracing, method and YARR JITs don't support arm64.mozilla_js_arm64.patch: 64-bit detection for arm64,finite→isfinite, and a debug-build-only declaration that was guarded byJS_METHODJIT.Platform macros
OOLITE_MAC_OS_XandOOLITE_SDLare both 1. A newOOLITE_MAC_COCOA_UI(OOLITE_MAC_OS_X && !OOLITE_SDL) guards the leftovers from the removed Cocoa front end, so those sites no longer pull in AppKit.OOLITE_MAC_OS_Xnow only selects Foundation and OS-level behaviour, such as log, cache and add-on paths and plist handling.OpenGL (macOS only offers a legacy 2.1 context alongside fixed-function GL)
ARB_framebuffer_object,APPLE_vertex_array_object,ARB_texture_float,ARB_color_buffer_floatandARB_draw_buffersare present.glGen/Bind/DeleteVertexArraysmap to the*APPLEfunctions andglClampColormaps toglClampColorARB. The MSAA colour buffer is a multisample renderbuffer, since multisample textures aren't available.#version 330prefix are translated to GLSL 1.20 (plusEXT_gpu_shader4) when they load (TranslateGLSL330To120inOOShaderProgram.m), so the shader files stay shared across platforms. To make that possible I rewrote twoswitchstatements as if/else and removed one interface block. Both changes are valid GLSL 3.30, so other platforms are unaffected.macOS app bundle and installer
post_build.shcreatesContents/MacOS,Contents/Resources(the game data),Contents/AddOnsand anInfo.plistgenerated fromResources/Info-gnustep.plistwith the Cocoa-only keys removed.Contents/Frameworkswith@rpathload paths, so the app runs without Homebrew. The bundle is ad-hoc signed../mk.sh pkg-dmg <type>(installers/macos/create_dmg_fn.sh) builds a compressed DMG with the app and an/Applicationslink../mk.sh installcopies the bundle to/Applications/Oolite.app.CI
build-all.yamlgains abuild-macosjob (deployment, test and dev onmacos-latest). The release job attaches the DMGs, its expected file count goes from 8 to 11, and it declarescontents: write, which forks need because their default token is read-only.test_builds.yamlgains amacosjob (build, smoke test and DMG). On macOS the smoke test uses the real video driver, because SDL's offscreen driver has no OpenGL there.Fixes in shared code
These were found while porting. They're needed on macOS and should also help elsewhere:
SDL_GetWindowPixelDensity, which is 1.0 on standard displays.addShipToShipyardcrash: with no personality given it insertednilinto a dictionary, which throws on GNUstep and Apple Foundation alike.stringByReplacingString:withString:in the HDR snapshot path is replaced withstringByReplacingOccurrencesOfString:withString:.macOS-only behaviour, guarded so other platforms are unchanged:
SDL_GetWindowSurface()on the GL window. On macOS it replaces the GL drawable and the window goes black. VSync usesSDL_GL_SetSwapInterval, and snapshots read the front buffer.hasBytesAvailable, because Apple's socket streams block in-read:and freeze the game loop. Connect with a plain non-blocking socket, becauseNSHostand CFNetwork's host lookup stalled for about 18 seconds on GitHub's macOS runners.Contents/MacOS,main()changes directory toContents, so the existingResources/andAddOns/lookups work unchanged.Testing
./mk.sh test devand./mk.sh test testpass;/Applications.clang-format22 is clean for the changed files,shellcheckis clean for the new scripts andactionlintis clean for the new jobs.Known limitations
macos-latestrunners today).Comparison with #761–#763
Both PRs share the core approach: Foundation + SDL3, a macro guarding the Cocoa-era code, legacy GL 2.1, and an interpreter-only arm64 SpiderMonkey. As I read them, the main differences are:
OoliteProject/mozillajs-macos, which doesn't exist yetmozillajs-linuxsource in-tree, cached in CIdevbuild only,.appuploaded as an artifactDocumentation/BUILDING-macOS.mdThe two would conflict if both were merged. I'm happy to rebase this onto #761 instead, or to move pieces such as the DMG packaging, the from-source SpiderMonkey build, the CI smoke test and the high-DPI fixes into follow-up PRs, whichever the maintainers prefer.