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
Default Build
Build and Run
Clean Build
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.
Native (Default)
Custom Machine
View Machine Config
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).
The EXTRAS environment variable enables optional build features defined in config/extra/with-*.mk.
Debug Builds
Debug Mode
Multiple Extras
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.
AddressSanitizer
UndefinedBehaviorSanitizer
MemorySanitizer
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.
libFuzzer
AFL++
Honggfuzz
Fuzzing with Sanitizers
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:
Fetches dependencies
Builds them using their native build scripts
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:
Generate configuration
Generate compiler and linker configuration for selected machine target
Compiler checks
Verify compiler capabilities and features
Discover targets
Discover available build targets from source tree
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