Skip to content

Build GBAx on macOS

Build for the correct architecture, package a DMG and understand signing and deployment.

4 min read Updated 28 Oct 2026

On this page

Use this guide when you want to change GBAx, inspect its implementation or reproduce its packaging process. If you only want to play, install a desktop download instead. A source build creates the application; it does not supply game files or a Nintendo BIOS.

Understand the build stages

CMake configures the project and finds dependencies. A compiler turns the C/C++ source into executable code. Packaging then collects the runtime libraries, Qt plugins, artwork resources and notices the application needs on another machine. Passing compilation is only one stage: an executable can work on a developer’s computer because it finds libraries that are missing from the package.

The release profile enables the Qt frontend and SDL audio/controller support. It does not build the separate SDL frontend. Optional integrations such as the application updater, FFmpeg recording, Lua scripting and Discord presence are disabled in Preview 1. Changing a profile option may introduce new dependencies and packaging work.

Get the matching source

git clone --branch v2.0.0-candidate-40705365475 --depth 1 https://github.com/gbaxemulator/GBAx.git
cd GBAx

The instructions below follow the Preview 1 release tag. To verify that you have the same revision described by this documentation, run:

git rev-parse HEAD

The expected commit is c1a826ae838f9b9226cdd2dd33b3dfea6893cbfb. A different checkout can have different dependencies or scripts. Keep your working changes in version control and use a fresh build directory when switching toolchains.

Use a fresh release build directory. The packaging scripts reject stale staging folders. Keep game files, saves and personal configuration outside the source tree.

Choose the target Mac

Use macOS 15 or newer, Xcode, Python, Qt 6.10.2 and Homebrew. Build separately on Apple Silicon and Intel with dependencies for that architecture. The two published DMGs are not a universal binary.

Match the architecture throughout the build

Use a native terminal, compiler and Homebrew installation for the architecture you intend to ship. An Apple Silicon build must not accidentally link an Intel-only dependency, and the Intel package needs its own native build. Check uname -m and the dependency locations before configuring the project.

The workflow uses separate macOS 15 runners for arm64 and x86_64. Its minimum macOS version reflects the native dependencies as well as Qt. Lowering only the deployment-target setting does not make a library built for a newer OS work on an older one. Install the Xcode development tools and complete their first-run setup before invoking the package script.

Install dependencies

brew install cmake ninja pkg-config sdl2 sdl3 libzip libpng sqlite zlib

Build and package

Point the script at your Qt macOS installation, then run it from the repository root:

export QT_ROOT_DIR="$HOME/Qt/6.10.2/macos"
bash tools/release/build-macos.sh

The script deploys the application bundle, checks it and produces a drag-to-Applications DMG under dist. Test from Applications, outside the source and build directories.

Signing and distribution

Unsigned test outputs have -unsigned in their names. Preview 1 is ad-hoc signed, not Apple Developer ID signed or notarized, so macOS can block it or show a security warning. The release guide documents the separate signing and notarization workflow. Keep certificates and signing credentials in repository secrets, never in source files.

Common Mac build failures

If Qt is not found, verify that QT_ROOT_DIR points to the Qt macOS kit rather than its parent installer directory. Architecture-related linker errors often mean that a Homebrew library or cached CMake configuration belongs to the other CPU type. Use a fresh build directory after correcting the toolchain.

If the application starts only from your development shell, inspect bundle deployment and the runtime report. A dependency path leading into your own Homebrew installation can explain why another machine fails. Signing or notarization failures belong to the distribution stage; they should not be reported as a game-emulation error.

Test the package, not only the build directory

Use the packaged output in a new location, ideally on a test machine without your development libraries. Check first-run setup, folder scanning with subfolders, a supported archive, background artwork, one game with sound, save/reload, controller reconnect and returning to the launcher. Keep notes for each platform; success on one OS does not establish that another package works.

The repository’s release workflow includes automated checks and deployed-runtime validation. These help detect missing resources and dependencies, but they do not replace interactive desktop tests or a game compatibility test suite. Keep the package’s licence and dependency notices when distributing a build.

Keep a useful build report

Record the commit, OS version, processor architecture, compiler and Qt version, the command you ran and the first meaningful error. For a configuration failure, keep the CMake output. For a link failure, keep the missing symbol/library message. For a runtime failure, state whether it occurs in the build tree, the extracted package or both. This makes it possible to distinguish a source error from a deployment problem.

Sources & implementation

Implementation references follow GBAx 2.0.0 Preview 1, commit c1a826ae. The hardware implementation derives from mGBA; these links point to the matching GBAx source, rather than assuming a newer upstream revision behaves identically.

Need help with a specific problem? Start with troubleshooting →