Toolchains¶
Catalyst toolchains are standalone YAML files that describe how Catalyst should
format compiler, linker, and archiver commands for a target environment. They let
projects override the built-in gcc-style defaults without modifying
Catalyst source code.
Overview¶
Projects opt into a custom toolchain by setting manifest.toolchain in their
profile configuration:
If manifest.toolchain is omitted, Catalyst uses its default gcc
toolchain definition.
Schema Overview¶
A Catalyst toolchain definition consists of one top-level section:
toolchain:
name: # Toolchain identifier
extensions: # Output file extensions and prefixes
flags: # Include/lib/define formatting templates
compiler: # C and C++ compilation commands
linker: # Executable and shared library link commands
archiver: # Static library archive command
toolchain¶
Defines the metadata and command templates Catalyst will use during generation.
| Field | Type | Default | Description |
|---|---|---|---|
name |
String | gcc |
Toolchain identifier. |
extends |
String | - | Optional path to a base toolchain file to inherit settings from. |
extensions |
Object | - | Output file extensions and library prefixes. |
flags |
Object | - | Templates for include paths, library paths, library names, runtime library paths, and preprocessor defines. |
compiler |
Object | - | C and C++ compiler executables, base flags, and command templates. |
linker |
Object | - | Executable and shared library linker executable, base flags, and templates. |
archiver |
Object | - | Static library archive template. |
Note
compiler.c.flags, compiler.cxx.flags, and linker.flags define the
compiler/linker flags for the target — this is the only home for build flags. The
manifest.tooling flag overrides (CCFLAGS/CXXFLAGS/LDFLAGS) were removed in 1.7.0;
set compiler.c.flags, compiler.cxx.flags, and linker.flags here instead.
toolchain.extensions¶
| Field | Type | Default | Description |
|---|---|---|---|
object |
String | .o |
Object file extension. |
executable |
String | "" |
Executable file extension. |
static_lib |
String | .a |
Static library extension. |
shared_lib |
String | .so |
Shared library extension. |
static_lib_prefix |
String | lib |
Prefix used for static library filenames. |
shared_lib_prefix |
String | lib |
Prefix used for shared library filenames. |
cpp_sources |
List of Strings | [".cpp", ".cxx", ".cc", ".cupp"] |
List of C++ source file extensions. |
headers |
List of Strings | [".h", ".hpp", ".hxx", ".hh", ".ipp", ".inl", ".tpp", ".cuh", ".tcc"] |
List of header file extensions. |
c_sources |
List of Strings | [".c", ".cu"] |
List of C / CUDA source file extensions (compiled with the C compiler rule). |
module_interfaces |
List of Strings | [".cppm", ".ixx", ".mpp", ".cxxm"] |
List of C++ module interface file extensions. |
clang_modules |
List of Strings | [".cppm", ".cxxm"] |
List of C++ module interface extensions that do not need explicit compiler flags to specify the module compilation type. |
bmi |
String | .pcm |
Compiled binary module interface (BMI) extension. |
library_scan |
List of Strings | Platform specific | Library extensions used to scan for vcpkg/dependency libraries (Windows defaults to [".lib"]; macOS defaults to [".a", ".dylib"]; others default to [".a", ".so"]). |
shell_scripts |
List of Strings | [".bat", ".cmd"] |
Windows batch/shell script extensions to search when resolving paths for command executables. |
toolchain.flags¶
| Field | Type | Default | Description |
|---|---|---|---|
include_dir |
String | -I{path} |
Template for an include directory flag. |
lib_dir |
String | -L{path} |
Template for a library search path flag. |
lib |
String | -l{name} |
Template for a library token. |
rpath |
String | -Wl,-rpath,{path} |
Template for one runtime library search path. Catalyst expands it once per unique resolved library directory. |
define |
String | -D{name}={value} |
Template for a preprocessor define with a value. |
define_empty |
String | -D{name} |
Template for a value-less preprocessor define. |
Note
flags templates interpolate {path}, {name}, and {value} placeholders.
toolchain.compiler¶
| Field | Type | Default | Description |
|---|---|---|---|
c |
Object | - | C compiler executable and command template. |
cxx |
Object | - | C++ compiler executable and command template. |
toolchain.compiler.c¶
| Field | Type | Default | Description |
|---|---|---|---|
executable |
String | cc |
C compiler executable. |
flags |
String or List | "" |
Base C compiler flags, interpolated as {cflags}. |
flags_append |
String or List | "" |
Appends flags to the inherited C compiler flags. |
flags_remove |
String or List | "" |
Removes matching flag tokens from the inherited C compiler flags. |
command |
String | {cc} {cflags} -MMD -MF {object}.d -c {source} -o {object} {includes} {defines} |
Command template for compiling C sources. |
toolchain.compiler.cxx¶
| Field | Type | Default | Description |
|---|---|---|---|
executable |
String | c++ |
C++ compiler executable. |
flags |
String or List | "" |
Base C++ compiler flags, interpolated as {cxxflags}. |
flags_append |
String or List | "" |
Appends flags to the inherited C++ compiler flags. |
flags_remove |
String or List | "" |
Removes matching flag tokens from the inherited C++ compiler flags. |
command |
String | {cxx} {cxxflags} -MMD -MF {object}.d -c {source} -o {object} {includes} {defines} |
Command template for compiling C++ sources. |
Note
Compiler command templates interpolate {cc} or {cxx}, plus
{cflags} or {cxxflags}, {source}, {object}, {includes}, and {defines}.
toolchain.linker¶
| Field | Type | Default | Description |
|---|---|---|---|
executable |
String | c++ |
Linker executable. |
flags |
String or List | "" |
Base linker flags, interpolated as {ldflags}. |
flags_append |
String or List | "" |
Appends flags to the inherited linker flags. |
flags_remove |
String or List | "" |
Removes matching flag tokens from the inherited linker flags. |
executable_command |
String | {linker} {objects} -o {output} {ldflags} {lib_dirs} {rpaths} {libs} |
Command template for building executables. |
shared_lib_command |
String | {linker} -shared {objects} -o {output} {ldflags} {lib_dirs} {rpaths} {libs} |
Command template for building shared libraries. |
Note
Linker command templates interpolate {linker}, {objects},
{output}, {ldflags}, {lib_dirs}, {rpaths}, and {libs}.
{rpaths} is the concatenation of flags.rpath expanded for every unique
library directory reported by resolved dependencies. Set flags.rpath to an
empty string to disable automatic runtime paths.
toolchain.archiver¶
| Field | Type | Default | Description |
|---|---|---|---|
executable |
String | ar |
Archive tool executable. |
command |
String | {archiver} rcs {output} {objects} |
Command template for building static libraries. |
Note
Archiver command templates interpolate {archiver}, {output},
and {objects}.
Example¶
toolchain:
name: msvc
extensions:
object: .obj
executable: .exe
static_lib: .lib
shared_lib: .dll
static_lib_prefix: ""
shared_lib_prefix: ""
flags:
include_dir: /I"{path}"
lib_dir: /LIBPATH:"{path}"
lib: "{name}.lib"
define: /D{name}={value}
define_empty: /D{name}
compiler:
c:
executable: cl.exe
command: '{cc} /c {source} /Fo"{object}" {cflags} {includes} {defines}'
cxx:
executable: cl.exe
command: '{cxx} /EHsc /c {source} /Fo"{object}" {cxxflags} {includes} {defines}'
linker:
executable: link.exe
executable_command: '{linker} {objects} /OUT:"{output}" {ldflags} {lib_dirs} {libs}'
shared_lib_command: '{linker} /DLL {objects} /OUT:"{output}" {ldflags} {lib_dirs} {libs}'
archiver:
executable: lib.exe
command: '{archiver} /OUT:"{output}" {objects}'
Fields omitted from a toolchain file retain their built-in defaults, so custom
toolchains only need to override the pieces that differ from the default
gcc behavior.
Toolchain Inheritance (extends)¶
To avoid duplicating toolchain configuration across different variants
(like debug and release, or different sanitizers), a toolchain file can declare a
base it inherits from using the extends key under toolchain.
toolchain:
extends: tc_base.yaml
name: "catalyst debug"
compiler:
cxx:
flags: "-std=c++23 -O0 -ggdb -DDEBUG"
Precedence & Merging¶
A toolchain configuration is resolved by folding from the base of the inheritance chain toward the leaf:
- Start from the built-in default
gcc-style defaults. - If
extendsis specified, resolve the base toolchain recursively first. - Apply the current file's own keys on top, overriding per leaf scalar.
Precedence order (lowest to highest):
Every unspecified key inherits from its parent base toolchain.
For flag fields (e.g. compiler.c.flags, compiler.cxx.flags, linker.flags), you can control composition using:
flags: Replaces the inherited flag string entirely.flags_append: Appends the provided flags to the inherited flags.flags_remove: Filters out matching space-separated tokens from the inherited flags.
Note
You can specify these as either a string or a list of strings. A list of strings is automatically space-separated.
Warning
You should generally pick one of the two composition paradigms per block: either wholesale replacement (flags) OR modification (flags_remove and flags_append).
If flags is specified, it completely replaces the inherited string, making flags_remove and flags_append in the exact same file largely redundant. (If multiple are used, the evaluation order is: flags overwrite, then flags_remove, then flags_append).
Path Resolution¶
The extends path is resolved relative to the directory of the file that declares it, not the current
working directory. This allows a set of toolchain files to remain relative to each other even if
the build runs from a different directory. Absolute paths are used verbatim.
Validation¶
- Cycle Detection: If a cycle is detected (e.g.
a.yamlextendsb.yamlwhich extendsa.yaml, or a file extends itself), it is reported as an error. - Missing Base: If the base file cannot be opened, it fails with an error indicating both the target file path and the referring file path.
- Depth Limit: There is a hard cap limit of 32 parent toolchain files in the inheritance chain to prevent pathological chains.