Skip to content

fix(sdl): example builds on Zig 0.16 macOS arm64 - #231

Merged
apotema merged 1 commit into
mainfrom
fix/sdl-arm-neon-h
May 26, 2026
Merged

fix(sdl): example builds on Zig 0.16 macOS arm64#231
apotema merged 1 commit into
mainfrom
fix/sdl-arm-neon-h

Conversation

@apotema

@apotema apotema commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

The SDL backend's example/ build was failing with ~5636 errors on macOS
arm64 + Zig 0.16. Reproduces on origin/main; not caused by #226's zon
bump. Pre-existing toolchain issue, now fixed.

Root cause

Zig 0.16's bundled clang headers (lib/include/arm_vector_types.h,
arm_neon.h) use the FP8 type __mfp8 and __builtin_neon_* intrinsics
that are gated on target features (+fp8, etc.) which aren't enabled by
default for the host's apple_m* CPU. SDL2's SDL_cpuinfo.h does
#if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON)
#include <arm_neon.h>, transitively pulling Zig's broken-for-this-CPU
header into the @cImport translation unit.

First 5 errors from the broken build:

arm_vector_types.h:20:9: error: type specifier missing, defaults to 'int'
  typedef __mfp8 mfloat8_t;
arm_vector_types.h:20:16: error: expected ';', found 'an identifier'
arm_vector_types.h:93:46: error: type specifier missing ...
  typedef __attribute__((neon_vector_type(8))) mfloat8_t mfloat8x8_t;
arm_vector_types.h:171:3: error: unknown type name 'mfloat8x8_t'
arm_neon.h:246:43: error: use of unknown builtin '__builtin_neon_vbfdotq_f32'

Fix

Define SDL_DISABLE_ARM_NEON_H (SDL's official escape hatch) at every
@cImport site for SDL2 in the backend:

  • backends/sdl/src/sdl.zig
  • backends/sdl/src/audio.zig (separate cImport for SDL_mixer)

We don't call NEON intrinsics from Zig — SDL still uses NEON internally
in its precompiled library — so disabling the transitive header include
is safe and surgical.

Verification (macOS arm64, Zig 0.16.0)

  • cd backends/sdl/example && zig build — green (was 5636 errors)
  • cd backends/sdl && zig build — green
  • cd backends/sdl && zig build test — green
  • cd backends/sdl && zig build -Dtarget=x86_64-linux-gnu — green
  • cd backends/sdl && zig build -Dtarget=x86_64-windows-gnu — green

(Example cross-compile to Linux still fails, but on a pre-existing
unconditional linkFramework("Cocoa") in example/build.zig — unrelated
to this fix.)

Related / upstream

The underlying issue — Zig 0.16 shipping FP8-aware arm_neon.h without
defaulting +fp8 for apple_m* CPUs — is arguably a Zig stdlib bug worth
filing upstream. Any C library that includes <arm_neon.h> from a public
header (not just SDL2) will hit this. Workaround here is SDL-specific;
a generalized fix would live in ziglang/zig.

Test plan

  • sdl example builds on macOS arm64
  • sdl backend builds + tests pass on macOS arm64
  • sdl backend cross-compiles to linux + windows
  • CI confirms green on all platforms

…mismatch

Zig 0.16's bundled clang ships an arm_neon.h that uses the FP8 type
`__mfp8` and `__builtin_neon_*` intrinsics gated on target features that
aren't enabled by default on macOS arm64. SDL2's SDL_cpuinfo.h transitively
includes <arm_neon.h> when __ARM_NEON is set, which triggered ~5636
@cImport translation errors:

  arm_vector_types.h:20: typedef __mfp8 mfloat8_t;
    error: type specifier missing, defaults to 'int'
  arm_vector_types.h:93: typedef ... mfloat8_t mfloat8x8_t;
    error: unknown type name 'mfloat8x8_t'
  arm_neon.h:246: __builtin_neon_vbfdotq_f32
    error: use of unknown builtin

SDL exposes SDL_DISABLE_ARM_NEON_H as the documented escape hatch for
exactly this case. We don't call NEON intrinsics from Zig — SDL still
uses NEON internally in its precompiled library — so disabling the
transitive header include is safe.

Applied to both @cImport sites (src/sdl.zig and src/audio.zig).
@cursor

cursor Bot commented May 26, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Compile-time C import workaround only; no runtime or API behavior changes, and NEON is not used from Zig code.

Overview
Fixes macOS arm64 + Zig 0.16 SDL backend and example builds that were failing with thousands of C translation errors when SDL pulled in <arm_neon.h> via SDL_cpuinfo.h.

Both SDL @cImport blocks now define SDL_DISABLE_ARM_NEON_H before including headers: the shared import in sdl.zig and the separate SDL_mixer import in audio.zig. That stops the broken FP8/NEON header chain from entering Zig’s @cImport units while SDL still uses NEON in its linked library. Comments in sdl.zig (and a short pointer in audio.zig) document the toolchain mismatch and why the define is safe.

Reviewed by Cursor Bugbot for commit 3be0098. Bugbot is set up for automated code reviews on this repo. Configure here.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request defines SDL_DISABLE_ARM_NEON_H as 1 before importing SDL2 headers in backends/sdl/src/audio.zig and backends/sdl/src/sdl.zig. This change prevents compilation errors on macOS arm64 with Zig 0.16 caused by a transitive inclusion of <arm_neon.h> and a mismatch with the FP8 type. There are no review comments, and I have no additional feedback to provide.

@apotema
apotema merged commit 5030a3d into main May 26, 2026
4 checks passed
@apotema
apotema deleted the fix/sdl-arm-neon-h branch May 26, 2026 19:03
apotema added a commit that referenced this pull request May 26, 2026
7 PRs since v0.34.1:
- #225 fix(raylib): takeScreenshot handles absolute paths (closes #224)
- #230 fix(raylib): replace rename trick with direct libc write
       (closes #229 — Linux EXDEV + Windows compile + Ubuntu X11)
- #231 fix(sdl): SDL_DISABLE_ARM_NEON_H for Zig 0.16 arm_neon.h mismatch
- #226 chore(backends): Zig 0.16 sweep on sdl + raylib + null (closes #221)
- #227 chore(bgfx): build cleanly on Zig 0.16.0 + zbgfx pin bump
       (closes #219)
- #228 chore(wgpu): build cleanly on Zig 0.16.0 + snorm-dev pin
       (closes #220, refs bronter/wgpu_native_zig#46)
- #216 fix(codegen): sanitize plugin idents in resolve() emit (closes #212)
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