Skip to main content

Build System

Compiler Backends

DCR supports 7 compilation backends. Selection is automatic based on file extension and build.compiler value.

BackendFilesWhen used
unix_cc.c, .cpp, .cxx, .cc, .Sgcc/clang on Linux/macOS/BSD
msvc.c, .cpp, .cxx, .ccWindows (cl, clang-cl)
gas.sARM/ARM64 assembler (no preprocessor)
nasm.asm, .sx86/x86_64 NASM assembler
masm.asmMASM (ml/ml64) on Windows
fasm.asm, .fasmFlat Assembler
llvm_ir.llLLVM IR via llc -filetype=obj

Qt Support

DCR provides native Qt support for automatic meta-object handling (MOC, UIC, RCC).

Enable it by setting build.qt = true in dcr.toml. DCR will automatically detect Qt-related files (.ui, .qrc, .h with Q_OBJECT) and process them.

[build]
qt = true

Note: Requires qt6 modules (Core, Widgets, Gui, Svg) installed via pkg-config.

Advanced customization is still possible via build.steps if special handling is needed:

[build.steps]
moc = "moc {in} -o {out}"

Unix CC

  • Compiler resolved via resolve_compiler(): DCR_COMPILER > DCR_CC > [toolchain] > build.compiler > PATH
  • Supports .d files for header dependency tracking
  • Flags: -std=, -MMD -MF, -c -o, -I, -L, -l
  • Conditional flags based on config:
    • freestanding or bare-metal target: -ffreestanding (compile), -nostdlib -static (link)
    • lto: -flto (compile + link)
    • panic = "abort": -fno-exceptions (C++ only), -fno-unwind-tables, -fno-asynchronous-unwind-tables

MSVC

  • Supports cl.exe and clang-cl.exe
  • Flags: /std:, /Fo:, /Fe:, /I, /link

GAS / NASM / MASM / FASM / LLVM-IR

  • GAS: -I, -c -o, --defsym
  • NASM: -I, -o, -D, -f (format: win64/elf64/macho64/macho32/elf32; bin when kind = "flat-bin")
  • MASM: /nologo /c /Fo<obj> <source>
  • FASM: <source> <output> (output path is the object file)
  • LLVM IR: -filetype=obj <source> -o <output>

Incremental Builds

Three levels of incrementality:

  1. mtime — if output is newer than all inputs, skip
  2. .d files — header change tracking (including transitive)
  3. SHA256 fingerprint — recompile if compiler flags changed (stored in .dcr_fingerprint)

Parallel Compilation

  • thread::scope for thread pool
  • Atomic task queue (AtomicU64)
  • Mutex on stdout (OUTPUT_MUTEX)
  • Thread count = available_parallelism(), capped by build.codegen-units if set

Build Kinds

KindTypePath (Linux example)
binExecutabletarget/<triple>/<profile>/<name> (.exe on Windows)
staticlibStatic librarytarget/<triple>/<profile>/lib<name>.a (.lib)
sharedlibDynamic librarytarget/<triple>/<profile>/lib<name>.so (.dll/.dylib)
efiUEFI applicationtarget/<triple>/<profile>/<name>.efi
elfELF without stdlibtarget/<triple>/<profile>/<name>
noneCompile only, no link
customFull filename+extension controltarget/<triple>/<profile>/<filename>.<extension>
flat-binRaw binaryASM: <stem>.bin (NASM -f bin / FASM / GAS·MASM·LLC via objcopy); C/C++: <name>.bin (link + objcopy)

Disk images ([archive])

After a successful build, if [archive] is present in dcr.toml, DCR formats a FAT volume and copies files from layout into the image. See dcr.toml → archive.

Build Steps

DCR supports pre-build and post-build steps:

  • build.steps — commands before compilation
  • build.post_steps — commands after compilation

Substitutions: {stem}, {in}, {out}, {profile}, {version}, {name}.

Example Qt codegen via build steps:

[build.steps]
moc = "moc {in} -o {out}"

pkg-config

Automatic lookup (read from raw config):

[build]
pkg_config = ["sdl2", "gl"]

DCR runs pkg-config --cflags sdl2 gl and pkg-config --libs sdl2 gl and adds results to compiler/linker flags.

Variable Substitution

Supported variables:

VariableDescription
{version}Package version
{version_major}Major version part
{version_minor}Minor version part
{version_patch}Patch version
{version_suffix}Suffix (e.g., -rc1)
{version_suffix_dash}Suffix with dash
{profile}Profile name (debug/release)
{name}Package name