Skip to content

Build Instructions using macOS 15 (Sequoia) and macOS 26 (Tahoe)

Install Homebrew

  • Run command in Terminal:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Tip

Installing Brew via the command above will automatically install the Xcode Command Line Tools. If for some reason you need to do this manually, run xcode-select --install via the Terminal app.

Install Qt 6

Note

If you only intend on building the firmware, and not simu, companion or simulator, this is not necessary, and you can skip to the next step.

brew install qt@6

Once Qt has been installed, you should set a couple environment variables (please modify according to the real installation paths):

export QTDIR=$(brew --prefix)/opt/qt@6
export QT_PLUGIN_PATH=$QTDIR/plugins

Please note that QT_PLUGIN_PATH is required to be able to run Companion from your build directory without having to build a DMG package first.

Install ARM toolchain

Download and install the ARM GCC toolchain from here (installs in /Applications/ArmGNUToolchain/):

If you install the .tar.xz archive manually instead of the .pkg, you may need to remove the macOS quarantine flag yourself. See https://disable-gatekeeper.github.io/ for details.

Other tools

brew install sdl2 sdl3 cmake uv

Note

Homebrew's sdl2 package is sdl2-compat, which depends on SDL3 at runtime. Both sdl2 and sdl3 must be installed before building Companion or a .dmg.

If you plan to run the standalone simulator for debugging:

brew install --cask xquartz

Download EdgeTX code

  • Checkout code
git clone --recursive https://github.com/EdgeTX/edgetx.git
  • Switch into the source directory:
cd edgetx

Install Python dependencies

Since Python 3.11+, macOS uses an externally managed Python environment. Create a project virtual environment with uv:

uv venv --python 3.14
source .venv/bin/activate
uv pip install -r requirements.txt

Activate the virtual environment in every new terminal session before building:

source .venv/bin/activate

Configure the build

mkdir -p build && cd build

Configure for RadioMaster TX16S (other radio flags):

cmake -DPCB=X10 -DPCBREV=TX16S \
   -DCMAKE_PREFIX_PATH=$QTDIR \
   -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
   -DARM_TOOLCHAIN_DIR=/Applications/ArmGNUToolchain/14.2.Rel1/arm-none-eabi/bin/ ..
Variable Purpose
CMAKE_PREFIX_PATH Path to your Qt installation ($QTDIR)
CMAKE_OSX_DEPLOYMENT_TARGET Minimum macOS version for Companion. 14.0 (Sonoma) is a convenient local-dev default; release builds (CI) target 11.0 for broader compatibility — pass -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 if you want a build matching what CI ships. If omitted entirely, no -mmacosx-version-min flag is passed and clang targets whatever OS version your Mac is running
ARM_TOOLCHAIN_DIR Path to ARM GCC binaries. Must end with /

Build firmware

cmake --build . --target arm-none-eabi-configure --parallel 4
cmake --build . --target firmware

The firmware binary is written to build/arm-none-eabi/firmware.bin.

Build Companion

Firmware and Companion are separate targets. Companion requires Qt, SDL2, and SDL3 (see above).

From the build directory:

source ../.venv/bin/activate
export QTDIR=$(brew --prefix)/opt/qt@6
export QT_PLUGIN_PATH=$QTDIR/plugins

cmake --build . --target native-configure --parallel 4
cmake --build . --target wasi-module --parallel 4
mkdir -p native/plugins
cp wasm/edgetx-*-simulator.wasm native/plugins/
cmake --build . --target companion --parallel 4

The application bundle is created at build/native/EdgeTX Companion 3.0.app (the version number matches your EdgeTX release).

Run Companion from the build directory

export QT_PLUGIN_PATH=$(brew --prefix)/opt/qt@6/plugins
open native/*.app

For the radio simulator to work when running from the build tree, copy the WASM module into the bundle:

cp wasm/edgetx-*-simulator.wasm native/*.app/Contents/MacOS/

Build a distributable .dmg

The package target lives in the native build tree, not in the top-level build directory.

mkdir -p native/plugins
cp wasm/edgetx-*-simulator.wasm native/plugins/ 2>/dev/null
cmake --build native --target package

The .dmg is written to build/native/edgetx-companion-<version>.dmg (the version number matches your EdgeTX release).

Open it and drag EdgeTX Companion into /Applications:

open native/edgetx-companion-*.dmg

The packaging step bundles Qt, SDL2, and SDL3 into the .app automatically, then verifies that nothing in the bundle still points at a library outside it. If that check fails, the build stops rather than producing a .dmg that only runs on your machine — most often because a dependency was picked up from Homebrew without being copied in. Pass -DCOMPANION_VERIFY_BUNDLE=OFF to package anyway.

Note

A locally built .dmg is not what CI ships. Homebrew's bottles are single-architecture and target your macOS version, so your build is arm64-only and requires the macOS you built it on. CI builds sdl2-compat and SDL3 from source as universal (x86_64 + arm64) binaries targeting macOS 11.0 — see .github/actions/build_companion/setup-sdl.sh. Both use the same sdl2-compat + SDL3 stack, so the code path is identical; only the slices and minimum OS differ.

Troubleshooting

Notes on compiling simulator plug-ins

When compiling simulator plug-ins (using cmake --build . --target libsimulator with the target properly configured), the product of this compilation will be a .dylib stored in your build directory. If you want the Companion or Simulator apps to be able to use it, you will need to copy it manually into the respective directories. Here is how it should look with a couple of plug-ins copied:

% ls -l companion.app/Contents/MacOS/
total 411976
-rwxr-xr-x  1 etx  staff  27908864 Jan  7 11:48 companion
-rwxr-xr-x  1 etx  staff  57089384 Jan  7 11:22 libedgetx-nv14-simulator.dylib
-rwxr-xr-x  1 etx  staff  61167768 Jan  7 08:44 libedgetx-tx16s-simulator.dylib
-rwxr-xr-x  1 etx  staff  60327272 Jan  5 12:48 libedgetx-x10express-simulator.dylib
-rwxr-xr-x  1 etx  staff   1849768 Dec 26 08:56 libedgetx-x9d+-simulator.dylib
-rwxr-xr-x  1 etx  staff   1881224 Dec 31 16:44 libedgetx-zorro-simulator.dylib

% ls -l simulator.app/Contents/MacOS/
total 392616
-rwxr-xr-x  1 etx  staff  57089384 Jan  7 11:22 libedgetx-nv14-simulator.dylib
-rwxr-xr-x  1 etx  staff  61168056 Jan  5 11:52 libedgetx-tx16s-simulator.dylib
-rwxr-xr-x  1 etx  staff  60327272 Jan  5 12:34 libedgetx-x10express-simulator.dylib
-rwxr-xr-x  1 etx  staff  21732144 Jan  7 11:48 simulator

Notes on possible error while trying to run build-companion.sh

If you encounter this error:

CPack: - Install project: EdgeTX []
CMake Error at /opt/homebrew/Cellar/cmake/3.27.7/share/cmake/Modules/BundleUtilities.cmake:458 (message):
  otool -l failed: 1

  error:
  /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic:
  can't open file: @rpath/libsharpyuv.0.dylib (No such file or directory)

Call Stack (most recent call first):
  /opt/homebrew/Cellar/cmake/3.27.7/share/cmake/Modules/BundleUtilities.cmake:527 (get_item_rpaths)
  /opt/homebrew/Cellar/cmake/3.27.7/share/cmake/Modules/BundleUtilities.cmake:614 (set_bundle_key_values)
  /opt/homebrew/Cellar/cmake/3.27.7/share/cmake/Modules/BundleUtilities.cmake:933 (get_bundle_keys)
  /Users/jean-christophedreyfus/Documents/edgetx/build/native/companion/src/cmake_install.cmake:180 (fixup_bundle)
  /Users/jean-christophedreyfus/Documents/edgetx/build/native/cmake_install.cmake:43 (include)


CPack Error: Error when generating package: companion
make: *** [package] Error 1

It can be fixed by entering the following command at terminal:

install_name_tool -change "@rpath/libsharpyuv.0.dylib" "$(brew --prefix)/lib/libsharpyuv.0.dylib" "$(brew --prefix)/lib/libwebp.7.dylib" && codesign --force -s - "$(brew --prefix)/lib/libwebp.7.dylib"