Skip to content

Fix macOS CI: build static SDL2 from source -- brew's sdl2 is now sdl2-compat without libSDL2.a - #118

Open
arekbr wants to merge 1 commit into
slajerek:masterfrom
arekbr:fix/ci-macos-static-sdl2
Open

Fix macOS CI: build static SDL2 from source -- brew's sdl2 is now sdl2-compat without libSDL2.a#118
arekbr wants to merge 1 commit into
slajerek:masterfrom
arekbr:fix/ci-macos-static-sdl2

Conversation

@arekbr

@arekbr arekbr commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

The macOS job dies in MTEngineSDL's Libtool step. The actual error is on the last line before the failure (the Usage banner above it is just what the new libtool prints on any error):

libtool: could not find 'libSDL2.a' for option -lSDL2

Root cause is outside both repos. Homebrew's sdl2 formula has become an alias for sdl2-compat (a dynamic shim over SDL3) and ships no static libSDL2.a anymore (formulae.brew.sh/formula/sdl2 is a 404 now). The brew install sdl2 step from afbc20a still succeeds -- it just installs something else than it did in June. That is why the last green run is from June: the formula switched underneath, and there were no pushes in between. Pinning the runner image would not help; homebrew-core is shared across images.

Fix: build-macos.sh builds static SDL2 2.32.10 from source and stages libSDL2.a into MTEngineSDL/platform/MacOS/libs/ -- the exact pattern the script already uses for uSockets.a two lines above. libs/ is the first -L path in the libtool invocation (it comes from the Xcode project's LIBRARY_SEARCH_PATHS), so the archive is found right where -lSDL2 looks for it.

Staging lives in build-macos.sh rather than the workflow on purpose: the script clones MTEngineSDL only when the directory does not exist, so a workflow step creating that path first would skip the clone. It also fixes local developer builds, not just CI.

UPDATE -- verified on real hardware. I ran this branch (plus the #117 fix, which master needs to compile at all) on a Mac Studio, arm64, macOS 26.5, Xcode 16.4 -- a full ./build-macos.sh from a fresh clone:

  • static SDL2 2.32.10 built from source and staged, libs/libSDL2.a (2.6 MB);
  • the whole build went through with zero errors, Retro Debugger.app produced (arm64, 36 MB), SDL_Init statically merged into libMTEngineSDL.a, no SDL in otool -L;
  • one correction to what I originally wrote here: with the file staged, the libtool command line still says -lSDL2 -- the full-path treatment applies only to uSockets.a, because its name has no lib prefix so xcodebuild cannot express it as -l (that was the real difference in the failing log, not the file's existence). The archive is found via the -L .../libs search path instead. The failing run's own error text ("could not find 'libSDL2.a' for option -lSDL2") shows the new libtool does process -l and searches for the archive -- it just had nowhere to find it.

Success criterion for the CI run (corrected): the Libtool .../libMTEngineSDL.a step completes and the job goes green -- the command line will still show -lSDL2, which is expected. The remaining variable this local run could not cover is the Xcode 26.6 libtool itself (my Mac has 16.4), so one CI run on this PR is still the final word -- please trigger the workflow.

🤖 Generated with Claude Code

…l2-compat

The macOS job dies in MTEngineSDL's Libtool step:

  libtool: could not find 'libSDL2.a' for option -lSDL2

Root cause is outside the repo: Homebrew's 'sdl2' formula has become an alias
for sdl2-compat (a dynamic shim over SDL3) and no longer ships a static
libSDL2.a. The 'brew install sdl2' step (added in afbc20a, back when the
formula was real SDL2) still succeeds -- it just installs something else now.
The last green run was in June, before the formula switch; pinning the runner
image would not help, since homebrew-core is shared across images.

Fix: build static SDL2 2.32.10 from source in build-macos.sh and stage
libSDL2.a into MTEngineSDL/platform/MacOS/libs/ -- the exact pattern already
used for uSockets.a two lines above. With the file present, Xcode passes
libtool a full path (as it does for uSockets.a in the failing log), so nothing
depends on how the new Xcode 26.6 libtool resolves -L/-l. Success criterion in
the CI log: the Libtool command line shows .../libs/libSDL2.a as a full path
instead of -lSDL2.

The staging happens in build-macos.sh rather than the workflow because the
script clones MTEngineSDL only when the directory does not exist -- a workflow
step preparing that path first would skip the clone and break the build. Also
works for local developer builds, not just CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant