This document covers the cross-platform build system used to compile Firestack for Android, iOS, macOS, Linux, and Windows. It explains the build orchestration via Makefile, the build environment setup via the make-aar script, cross-compilation tools (gomobile and xgo), runtime patching mechanisms, and the various build artifacts produced for each platform.
The Firestack build system is orchestrated through a Makefile-based workflow that coordinates multiple specialized tools to produce platform-specific artifacts. The system supports five target platforms through two distinct build toolchains.
Title: Build System Components and Data Flow
Sources: Makefile1-151 go.mod1-28 make-aar1-103 tools/runtime_write_err_android.patch1-23
gomobile is used to compile Go code into Android AAR packages and iOS/macOS XCFrameworks. The tool is installed and initialized through the Makefile Makefile98-102
Installation and Initialization:
| Step | Command | Purpose |
|---|---|---|
| Install | go install golang.org/x/mobile/cmd/gomobile@latest | Download gomobile binary Makefile99 |
| Install overlay | go install github.com/felixge/go-patch-overlay@latest | Install patching tool Makefile100 |
| Initialize | gomobile init | Set up gomobile SDK Makefile101 |
Gomobile Bind Configuration:
The GOBIND variable defines common gomobile parameters:
-trimpath: Remove absolute paths from binaries Makefile25-javapkg com.celzero.firestack: Set Java package name for generated bindings Makefile25Android-Specific Configuration:
ANDROID23: Targets Android API 23 with the android build tag Makefile27ANDROID23_DEBUG: Adds the debuglog tag to enable runtime crash logging output Makefile33Sources: Makefile4-5 Makefile25-33 Makefile98-102
xgo is used to cross-compile Go code for Linux and Windows desktop platforms Makefile8 It supports cross-compilation from any host OS.
Build Targets:
| Target | Architecture | Output |
|---|---|---|
linux/amd64 | 64-bit Linux | tun2socks Makefile82-85 |
windows/386 | 32-bit Windows | tun2socks.exe Makefile86-89 |
XGO LDFLAGS:
XGO_LDFLAGS='-s -w -X main.version=$(COMMIT_ID)' Makefile11
-s: Strip symbol table.-w: Strip DWARF debugging information.Sources: Makefile8 Makefile11 Makefile82-89 Makefile103-104
The build system applies runtime patches to the Go standard library using go-patch-overlay. This mechanism allows modification of runtime behavior without forking the Go compiler.
Title: Patching Workflow for Android Runtime
Overlay Generation:
The BUILD_OVERLAY target invokes GOPATCHOVERLAY to create a JSON overlay from the provided patch file Makefile78-80
The patch modifies src/runtime/write_err_android.go to change the Android log level to ANDROID_LOG_FATAL (7) and the log ID to LOG_ID_CRASH (4) to enhance crash diagnostics tools/runtime_write_err_android.patch9-20
Sources: Makefile78-80 tools/runtime_write_err_android.patch1-23
Firestack uses go:linkname to manipulate Go runtime internals, specifically to improve observability on Android where the OS defaults can hinder crash diagnostics.
Core Overreach Mechanism:
The build system uses the -checklinkname=0 linker flag to bypass Go 1.26 restrictions on go:linkname usage Makefile13-16 go.mod3 This allows the codebase to override runtime.secureMode.
Exposed Runtime Functions:
The Makefile specifically references overriding runtime.secureMode via the core/overreach.go implementation Makefile14-16 The LDFLAGS use -checklinkname=0 to enable these runtime modifications.
Sources: Makefile13-16 go.mod3
The build system produces two primary AAR packages for Android:
Release AAR (tun2socks.aar):
Compiled using ANDROID_BUILD_CMD which includes -ldflags $(LDFLAGS) and -overlay=$(BUILD_OVERLAY) Makefile57-58 The LDFLAGS include -s -w to strip symbols Makefile16
Debug AAR (tun2socks-debug.aar):
Compiled using ANDROID_DEBUG_BUILD_CMD which includes -ldflags $(LDFLAGS_DEBUG) Makefile60-61 These flags do not strip symbols Makefile13
Debug Symbol Management:
The system includes a routine to extract debug symbols from the unstripped AAR. It uses llvm-objcopy to extract debug info into separate files, strips the original .so files, and repacks the AAR to minimize distribution size while retaining symbols for post-mortem analysis Makefile110-132
Sources: Makefile57-77 Makefile110-132
The XCFramework is a multi-platform bundle supporting iOS devices, iOS Simulator, and macOS Makefile91-92
Sources: Makefile91-92
Desktop executables are built using xgo for cross-compilation of the ELECTRON_PATH (github.com/celzero/firestack/outline/electron) Makefile7-8
| Target | Makefile Recipe |
|---|---|
| Linux | $(XGO) ... --targets=linux/amd64 Makefile83 |
| Windows | $(XGO) ... --targets=windows/386 Makefile87 |
Sources: Makefile82-89
The build system defines specific LDFLAGS for release and debug modes.
| Flag | Purpose |
|---|---|
-checklinkname=0 | Allows use of go:linkname for runtime hooks Makefile16 |
-w -s | Strips DWARF and symbol table for release Makefile16 |
-X ...Date=$(DATESTR) | Injects build date into intra/core.Date Makefile16 |
-X ...Commit=$(COMMIT_ID) | Injects commit hash into intra/core.Commit Makefile16 |
CGO LDFLAGS:
CGO_LDFLAGS includes -Wl,-z,max-page-size=16384 for compatibility with Android 15+ 16KB page size requirements Makefile20
Sources: Makefile13-20
The make-aar script handles environment setup and invokes Makefile targets. It is designed to work in both local development and CI/CD environments like Jitpack.
Title: make-aar Environment Initialization
NDK Version Selection:
The script checks if NDKVER is set; if not, it defaults to ANDROID_NDK_LATEST_HOME make-aar46-61 For Jitpack builds, NDKVER is explicitly set to 28.2.13676358 jitpack.yml7
Go Installation:
If the first argument is go, the script downloads Go 1.26.4, verifies the SHA256 checksum, and sets up the GOPATH and PATH make-aar63-78
Sources: make-aar15-103 jitpack.yml1-24
The go.mod file manages all Go dependencies go.mod1-56
Key Dependencies:
golang.org/x/mobile: Used for gomobile commands go.mod24github.com/crazy-max/xgo: Used for desktop cross-compilation go.mod18gvisor.dev/gvisor: Core network stack go.mod27golang.zx2c4.com/wireguard: WireGuard protocol implementation go.mod26Sources: go.mod1-56
Refresh this wiki