Skip to content

In macOS Tahoe, Apple Silicon the chapter 1 project is not building #81

Open

Description

@johan718

I opened the macOS project Chapter01-mac.xcodeproj in Xcode 26.2, running on macOS 26.2, running on my M1 macbook pro, and I tried building it by clicking on the play button. I get about 15 undefined symbol errors, for example, Undefined symbol: _SDL_CreateRenderer. See the image below. It is not finding any of the SDL definitions, apparently.

Image

Activity

  1. chalonverse commented on Jan 23, 2026

    @chalonverse
    Contributor

    I think this is likely because the libraries included are for Intel and not M1, since when I made the repo 8 years ago, M1s did not exist.

    Let me try to see if I can just replace the libs with newer ones that are universal.

  2. changed the title [-]In macOS Tahoe the chapter 1 project is not building[/-] [+]In macOS Tahoe, Apple Silicon the chapter 1 project is not building[/+] on Jan 24, 2026
  3. mtakagi commented on Oct 8, 2026

    @mtakagi

    The prebuilt macOS libraries committed in this repository are x86_64-only, so they cannot be linked into an arm64 binary. Xcode on Apple Silicon builds arm64 by default (the .xcodeproj files here do not pin ARCHS), and the linker silently skips a library whose architecture does not match — which surfaces as every SDL symbol being undefined.

    You can confirm it on your machine:

    lipo -archs External/SDL/lib/mac/libSDL2-2.0.0.dylib
    # x86_64

    I checked the Mach-O header of every dylib under External/, and all of them are thin x86_64:

    Library Architectures
    External/SDL/lib/mac/libSDL2-2.0.0.dylib x86_64
    External/SDL/lib/mac/libSDL2_image-2.0.0.dylib x86_64
    External/SDL/lib/mac/libSDL2_mixer-2.0.0.dylib x86_64
    External/SDL/lib/mac/libSDL2_ttf-2.0.0.dylib x86_64
    External/SDL/lib/mac/libfreetype.6.dylib x86_64
    External/SDL/lib/mac/libpng16.16.dylib x86_64
    External/GLEW/lib/mac/libGLEW.2.1.0.dylib x86_64

    That matches the age of the code — these predate Apple Silicon. Note that libGLEW is in the same state, so the OpenGL chapters (Chapter05 onward) will hit the same wall once Chapter01 links.

    Workarounds

    1. Use arm64 SDL from Homebrew (least work)

    brew install sdl2 sdl2_image sdl2_ttf sdl2_mixer

    Then, in the target's build settings:

    • HEADER_SEARCH_PATHS: add /opt/homebrew/include, remove $(SRCROOT)/../external/SDL/include
    • LIBRARY_SEARCH_PATHS: add /opt/homebrew/lib, remove $(SRCROOT)/../external/SDL/lib/mac
    • OTHER_LDFLAGS: replace -lSDL2-2.0.0, -lSDL2_image-2.0.0, -lSDL2_ttf-2.0.0, -lSDL2_mixer-2.0.0 with -lSDL2, -lSDL2_image, -lSDL2_ttf, -lSDL2_mixer

    Also delete (or guard) the shell-script build phase that copies ../external/{SDL,GLEW}/lib/mac/*.dylib into $BUILD_DIR — with Homebrew's dylibs resolved through their install names, the copy is unnecessary and the cp will fail once those paths are gone.

    2. Replace the bundled dylibs with universal ones

    Build SDL for both architectures and lipo -create them, or take the universal dylibs from the official SDL2 release DMG, and drop them into External/SDL/lib/mac/ under the same file names. Nothing in the project files has to change this way, so it is the smallest diff if you want to keep the repository layout intact.

    3. Build the x86_64 slice and run under Rosetta

    Setting ARCHS to x86_64 will link against the existing dylibs. It does work, but it needs Rosetta installed and leaves you on an emulated target, so I would treat it as a last resort rather than a fix.

    4. Build with CMake instead of the Xcode projects

    If what you want is to work through the book rather than to use these specific Xcode projects,
    this class of problem disappears if the dependencies are built from source. The difference is
    structural:

    Xcode / Visual Studio projects here CMake + FetchContent
    SDL, GLEW prebuilt binaries committed under External/ cloned and compiled during the build
    Architecture whatever the binaries were built for in 2018 (x86_64) whatever the host is, arm64 included
    Platform coverage one project file per chapter per IDE one build that covers macOS, Windows, Linux

    The second row is the whole point: when the compiler produces SDL for the machine doing the
    build, there is no architecture left to mismatch. No lipo, no Rosetta, no per-platform
    conditionals.

    I worked through the book this way and put it up here, in case it is useful as a reference:
    https://github.com/mtakagi/GameProgrammingCpp (English README)

    All 14 chapters build, and CI runs them on GitHub Actions' macos-26-arm64 image (macOS 26
    Tahoe, Apple Silicon — the same environment as this report) alongside Windows and Linux. There
    is no architecture-specific code in the CMake files; the only thing the macOS job needs is the
    SDL build dependencies, and even those only on Linux.

    Two caveats so you know what you would be getting:

    • It is a transcription, not a copy. The code is reimplemented in C++23 (std::ranges,
      constexpr, smart pointers in places), so it reads differently from the listings in the book.
      Code comments are in Japanese, though the README is available in English.
    • The book's assets are not redistributed, so you still copy each chapter's Assets directory
      out of this repository. FMOD (Chapter07 onward) also still has to be installed separately —
      that one is a prebuilt library, so make sure to get a 2.x release, which ships universal
      binaries for macOS.

    Feel free to lift just the CMakeLists.txt approach if you would rather keep the book's original
    code and only replace the build system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions