Packages are defined by TOML manifests.
Targets
A package can define as many executables, libraries, tests, and examples as it would like. These are called targets. They have fields like source, or include, or system_deps, and most fields can be configured at the package level for all targets or for an individual target.
[package]
include = ['common']
[[lib]]
source = ['source/lib.c']
include = ['source/lib']
[[example]]
source = ['example/foo/main.c']
[[test]]
source = ['test/main.c', 'test/foo.c']
define = ['SOMETHING']
system_deps = ['m']A [[bin]] and a [[script]], for instance, are both executables, but their difference isn’t strictly cosmetic. [[bin]] entries are taken to be exports of your package, able to be pulled in by consumers. [[script]] entries aren’t. [[test]] entries are executed in spn test, and compiled to test/ instead of bin/.
Target fields
source
include and headers
define and flags
system_deps
deps
kinds
cxx
System dependencies
Conditional configuration
Any field in your package can be keyed on any fact of the build (target OS, architecture, ABI, build mode, optimization level, sanitizer settings). Clauses are structured data, not a DSL, and an entry with multiple clauses gets them ANDed together. Here’s some common examples:
source = [
{ path = "source/backend/win32.c", when = { os = "windows" } },
{ path = "source/backend/posix.c", when = { os = { not = "windows" } } },
]
flags = [
{ value = "-mfpu=neon", when = { os = "linux", arch = "aarch64" } },
]
define = [
{ value = "USE_DEBUG_ALLOC", when = { mode = "debug", sanitize_address = false } },
]
system_deps = [
{ value = "pthread", when = { os = { not = "windows" } } },
]
deps = [
{ pkg = "tracy", when = { mode = "debug" } },
]when clauses
Fact keys
Options as keys
Options declared in the manifest work as keys, too, so a feature flag can gate sources and dependencies together:
[options.freetype]
type = "bool"
default = true
define = "UI_FREETYPE"
[[lib]]
name = "ui"
source = [
{ path = "source/text_freetype.c", when = { freetype = true } },
]
deps = [
{ pkg = "freetype", when = { freetype = true } },
]Options
Packages provide options. Options can be enumerations or booleans; enums are mutually exclusive, and an unresolvable conflict is a build error. Booleans are additive. For example:
[options.tls]
type = "enum"
values = ["schannel", "openssl", "off"]
default = [
{ when = { os = "windows" }, value = "schannel" },
{ when = { os = { not = "wasi" } }, value = "openssl" },
{ value = "off" },
]
[options.zstd]
type = "bool"
default = falseConsumers can then set these options
Platforms
macOS
[package.macos]
min_os = { major = 12 }
[lib.macos]
frameworks = ["Cocoa", "IOKit", "CoreVideo", "OpenGL"]When linking, your binary’s min_os is the max across everything in it. If a dependency needs macOS 12, your binary targets macOS 12.
Windows
[[bin]]
# ...
windows = { subsystem = "windows" }