Documents
buildstream
buildstream
Type
External
Status
Published
Created
Jun 13, 2026
Updated
Jun 13, 2026
Source
View

BuildStream Element Reference#

Load when writing, editing, or reviewing BuildStream .bst element files.

When NOT to Use#

  • End-to-end workflow for adding a new package → add-package.md
  • Diagnosing build failures → debugging.md
  • Understanding the CI pipeline → ci.md
  • Managing junction overrides → bst-overrides.md

Quick Recipes#

GoalCommand
Validate full element graph (no build)just validate
Inspect single element depsjust bst show bluefin/<name>.bst
Build one elementjust bst build bluefin/<name>.bst
Enter build sandboxjust bst shell --build bluefin/<name>.bst
Track a git/tarball refjust bst source track bluefin/<name>.bst
List built element contentsjust bst artifact list-contents bluefin/<name>.bst
View build logjust bst artifact log bluefin/<name>.bst
Delete cached buildjust bst artifact delete bluefin/<name>.bst
Full image buildjust build
All available recipesjust --list

Variables#

VariableExpands ToNotes
%{install-root}Staging directoryAlways prefix install paths with this
%{prefix}/usr
%{bindir}/usr/bin
%{indep-libdir}/usr/libFor systemd units, presets, sysusers, tmpfiles
%{datadir}/usr/share
%{sysconfdir}/etcRarely used in GNOME OS elements
%{install-extra}Empty hookConvention: always end install-commands with this
%{go-arch}amd64/arm64/riscv64Defined in project.conf per-arch
%{arch}x86_64/aarch64/riscv64Raw architecture name
strip-binariesSet to "" to disableRequired for non-ELF elements (fonts, configs, pre-built)
overlap-whitelistpublic: bst: overlap-whitelist:List of paths allowed to overlap between elements

Element Kinds#

KindUse Case
manualCustom build/install, pre-built binaries, config files
mesonGNOME libraries/apps
makeMakefile projects, Go with vendored deps
autotoolsLegacy C projects
make + cargo2Rust projects (see packaging-rust.md)
cmakeCMake projects
importDirect file placement (no build)
stackDependency aggregation, arch dispatch — produces zero filesystem output
composeLayer filtering (exclude debug/devel)
scriptOCI image assembly
collect_initial_scriptsCollect systemd preset/sysusers/tmpfiles from deps

Source Kinds#

Source KindUse Case
git_repoMost elements
tarRelease tarballs. Add base-dir: "" if tarball has no wrapping directory.
remoteSingle file download (not extracted). Use directory: to place into a subdirectory.
localFiles from repo's files/ directory
cargo2Rust crate vendoring. Generate with files/scripts/generate_cargo_sources.py.
go_moduleGo module deps (one per dep)
git_moduleGit submodule checkout
patch_queueApply patches directory
gen_cargo_lockGenerate Cargo.lock from base64

Command Hooks#

SyntaxMeaning
(>):Append to inherited command list from element kind
(<):Prepend to inherited command list
(@):Include a YAML file
(?):Conditional block (evaluates options like arch)

Convention: always end install-commands with %{install-extra}.

BST Weak-Key Caching Bug#

Symptom: Adding a new package to deps.bst (kind: stack) does NOT trigger a rebuild of downstream OCI image layers (kind: compose). New package is missing from the final image even though bst show lists it.

Root cause: In BST non-strict mode, the "weak key" for a kind: stack element is computed from its direct dependency names only, not their content hashes. Changing what a compose element transitively depends on via a stack does not change the compose element's weak key → BST considers it cache-hit → skips rebuild.

Workaround: Force-invalidate the cache of a kind: compose element that directly depends on the stack by making any content change to one of its direct dependencies.

Real fix: Use bst build in strict mode: just bst --no-cache-buildtrees build oci/bluefin.bst.

ECL / Common Lisp Packaging#

FactDetail
Must use -std=gnu99ECL's fpe_x86.c uses bare asm() — invalid under -std=c99
Must use --with-gmp=/usrWithout this, ECL bundles its own GMP and propagates -fasm which breaks configure
ecl --load spawns gccAny element calling ecl --load at build time needs gcc in build-depends
gitlab.common-lisp.net sourcesBST's dulwich cannot parse this git protocol — use kind: tar with GitLab archive URL

Lessons Learned#

Option names cannot contain hyphens (2026-06-07)#

BST option names only allow alphanumeric characters and underscores. A name like my-option silently fails or causes a parse error. Use my_option instead. This trips up agents that copy option names from CLI flags (which typically use hyphens).

# ❌ wrong
options:
  my-arch:
    type: arch

# ✅ correct
options:
  my_arch:
    type: arch

(>): append syntax replaces the entire command list if used incorrectly (2026-06-07)#

The (>): syntax appends to the inherited command list from the element kind. If you write it as a key at the wrong indent level, BST silently ignores it and uses only your commands, dropping the kind's built-in build steps. Always verify the final command list with just bst show --format '%{name}: %{build-commands}' bluefin/<name>.bst before building.

kind: stack elements produce no filesystem output — they are dep aggregators only (2026-06-07)#

deps.bst is intentionally kind: stack. That means it has zero filesystem output. Only kind: compose and kind: script elements produce filesystem artifacts. If a new layer element is accidentally typed as kind: stack, it will build successfully but the image layer will be empty. Always verify with grep '^kind:' elements/oci/layers/bluefin.bst.