Skip to main content
Firedancer uses a custom GNU Make-based build system focused on simplicity and robustness. It should be trivial to build Firedancer on a fresh installation of an arbitrary GNU/Linux distribution.

Quick Start

make -j
# Parallel build for native machine

Build System Overview

The project uses the build process of a typical statically linked C application for Linux.

Build Process Flow

┌────────────┐
│   C/C++    │  cc
│  sources   ├─────────────┬──────────────────────────────────────────┐
└────────────┘             │                                          │ cc
                           │                                          │
┌────────────┐       ┌─────▼─────┐       ┌─────────────┐       ┌──────▼───────┐
│  Assembly  │  as   │  Static   │  ar   │   Static    │  cc   │  Executable  │
│  sources   ├───────►  Objects  ├───────►  Libraries  ├───────►   Binaries   │
└────────────┘       └─────▲─────┘       └─────────────┘       │              │
                           │                                   │   Shared     │
┌────────────┐             │                                   │   Objects    │
│ Generated  │  cc         │                                   └──────▲───────┘
│   C code   ├─────────────┤                                          │
└────────────┘             │                                          │ cc
                           │                                          │
┌────────────┐             │                                   ┌──────┴───────┐
│  Embedded  │  cc         │                                   │  External    │
│   files    ├─────────────┘                                   │  Static      │
└────────────┘                                                 │  Libraries   │
                                                               └──────────────┘

Compile Units

A compile unit is a set of:
  • C/C++ files
  • Assembly files
  • Embedded files (binary content included via .incbin assembler directive)
Each compile unit gets compiled into a static object by invoking the GCC or Clang frontend.
On Linux, compile units are position-independent to support ASLR (Address Space Layout Randomization).

Machine Targets

The MACHINE environment variable allows building for different machine configurations.
make -j
# Equivalent to: MACHINE=native make -j

Default Machine

The default machine is native, which auto-detects your system configuration. The “Frankendancer” build target (fdctl) only targets x86_64 with a Haswell-like minimum feature set (AVX2, FMA).

Build Extras

The EXTRAS environment variable enables optional build features defined in config/extra/with-*.mk.

Debug Builds

make -j EXTRAS="debug"
# Enables with-debug.mk extra

Sanitizer Builds

Sanitizers bake in various runtime checks for development and testing.
Using sanitizers is not recommended for production builds.
make CC=clang EXTRAS=asan
# Detects invalid memory accesses
MemorySanitizer Special Requirements: MemorySanitizer requires all dependencies to be recompiled:
./deps.sh +msan
make CC=clang EXTRAS=msan

Fuzzing Builds

Fuzzers can be combined with sanitizers to find bugs more effectively.
make CC=clang EXTRAS=fuzz
# Requires Clang with libFuzzer support

Code Generation

Generated code is checked into the repository to minimize tooling dependencies.
Code generation tools are only required during development. All code generation tools are written in Python 3.9.

Dependencies

System Dependencies

Firedancer depends on:
  • GNU C Library (glibc) - linked dynamically
  • C++ standard library - linked dynamically
Example dynamic dependencies:
$ ldd build/native/gcc/bin/fdctl
        linux-vdso.so.1 (0x00007ffce652e000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f0d0398c000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f0d03788000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f0d033f3000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f0d03071000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f0d02e59000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0d02c39000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f0d02874000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0d097e0000)

Out-of-tree Dependencies

Firedancer aims for zero out-of-tree library dependencies. For practicality, some large external dependencies are fetched externally. The deps.sh script:
  1. Fetches dependencies
  2. Builds them using their native build scripts
  3. Installs includes and static libraries into opt/ directory
The compiler discovers these via:
-isystem ./opt/include -L./opt/lib

Build Configuration

Makefile Evaluation Steps

Each time the Makefile is evaluated:
1

Generate configuration

Generate compiler and linker configuration for selected machine target
2

Compiler checks

Verify compiler capabilities and features
3

Discover targets

Discover available build targets from source tree
4

Execute build rules

Execute build rules until selected targets are met

Configuration Files

Build configuration is spread across:
  • GNUmakefile - Main entry point
  • config/machine/*.mk - Machine-specific settings
  • config/extra/with-*.mk - Optional features
  • config/everything.mk - Global build rules
  • src/**/Local.mk - Per-module build rules

ABI Stability

Firedancer does not aim to be ABI-stable, with a few exceptions.
Symbols may change or disappear arbitrarily between different versions of the source code.

Cross-compiler Stability

The C parts of the project try to achieve cross-compiler stability. It should be fine to link together units compiled with:
  • Different versions of GCC
  • A mix of GCC and Clang (from the same Firedancer revision)

Stable ABI Components

Some small parts explicitly offer a stable ABI for use as a shared library:
  • Cross-client compatibility layer
  • Differential fuzzing targets

Building on Systems with CPU Isolation

If you have kernel CPU isolation enabled (e.g., isolcpus in the kernel command line), make will typically only use non-isolated CPUs for the build.
See the make-j script in contrib/ for help building efficiently on systems with CPU isolation enabled.

Common Build Targets

make -j
# Build all targets for native machine

Build docs developers (and LLMs) love