AgentSkillsCN

buildstream-element-reference

适用于编写、编辑或审查 BuildStream .BST 元素文件——提供变量名、元素类型、源类型、命令钩子、Systemd 路径以及层结构。

SKILL.md
--- frontmatter
name: buildstream-element-reference
description: Use when writing, editing, or reviewing BuildStream .bst element files — provides variable names, element kinds, source kinds, command hooks, systemd paths, and layer structure

BuildStream Element Reference

Quick-reference for authoring .bst elements in the bluefin-egg project. Look up variables, element kinds, source kinds, and common patterns here. For packaging workflows, see the packaging-pre-built-binaries skill.

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. Declared under public: block

Element Kinds

KindUse CaseExamples
manualCustom build/install, pre-built binaries, config filesbrew, brew-tarball, tailscale-x86_64, jetbrains-mono
mesonGNOME libraries/appsgsconnect, ptyxis
makeMakefile projects, Go with vendored depspodman, skopeo
autotoolsLegacy C projectsgrub, firewalld, openvpn
make + cargo2Rust projects (actual pattern used)just, bpftop, virtiofsd, bootc. See packaging-rust-cargo-projects
cmakeCMake projectsfish
importDirect file placement (no build)systemd-presets
stackDependency aggregation, arch dispatchdeps.bst, tailscale.bst
composeLayer filtering (exclude debug/devel)bluefin-runtime.bst
scriptOCI image assemblyoci/bluefin.bst
collect_initial_scriptsCollect systemd preset/sysusers/tmpfiles from depsoci/layers/bluefin-stack.bst (gnome-build-meta plugin)

Source Kinds

Source KindUse CaseExamples
git_repoMost elementsbrew, common, jetbrains-mono
tarRelease tarballs. Add base-dir: "" if the tarball has no wrapping directory (e.g., fzf ships a bare binary at root). Without it, BuildStream fails with Could not find base directory matching pattern: *tailscale-x86_64, wallpapers, fzf
remoteSingle file download (not extracted)brew-tarball. Use directory: to place into a subdirectory (critical for Zig offline builds)
localFiles from repo's files/ directoryplymouth-bluefin-theme
cargo2Rust crate vendoringbootc, just. Generate with files/scripts/generate_cargo_sources.py from Cargo.lock
go_moduleGo module deps (one per dep)git-lfs (in freedesktop-sdk)
git_moduleGit submodule checkoutcommon (bluefin-branding)
patch_queueApply patches directorytoolbox
gen_cargo_lockGenerate Cargo.lock from base64zram-generator

Command Hooks

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

Convention: always end install-commands with %{install-extra} so downstream elements can extend.

Multi-Arch Dispatcher Pattern

BuildStream does NOT support variable substitution in source URLs. When a source URL contains an architecture string (like amd64 or arm64), you cannot use %{go-arch}. Instead, create per-arch elements and a dispatcher:

yaml
# tailscale.bst (dispatcher)
kind: stack
(?):
- arch == "x86_64":
    depends:
      - bluefin/tailscale-x86_64.bst
- arch == "aarch64":
    depends:
      - bluefin/tailscale-aarch64.bst

Each per-arch element has its own source URL with the hardcoded architecture string. See the packaging-pre-built-binaries skill for the complete pattern.

Zig Build Pattern

Zig projects use kind: manual with custom zig build commands and many remote sources with directory: for offline dependency resolution. See the packaging-zig-projects skill for the complete workflow. Note: No Zig elements currently exist in the build; the skill is preserved for future use.

Layer Chain

How elements flow into the final OCI image:

code
element → deps.bst (stack)
  → bluefin-stack.bst (stack, adds gnomeos-stack)
    → bluefin-runtime.bst (compose, excludes devel/debug/static-blocklist)
      → oci/layers/bluefin.bst (compose, excludes debug/extra/static-blocklist)
        → oci/bluefin.bst (script, assembles OCI with parent gnomeos image)

To add a new package to the image: add it as a dependency of elements/bluefin/deps.bst.

Systemd Integration Paths

WhatInstall PathCommand Pattern
Service files%{indep-libdir}/systemd/system/install -Dm644 -t "%{install-root}%{indep-libdir}/systemd/system"
User services%{indep-libdir}/systemd/user/Same pattern with /user/
System presets%{indep-libdir}/systemd/system-preset/install -Dm644 ... 80-<name>.preset
User presets%{indep-libdir}/systemd/user-preset/Same pattern
sysusers%{indep-libdir}/sysusers.d/install -Dm644 -t ... sysusers.d
tmpfiles%{indep-libdir}/tmpfiles.d/install -Dm644 -t ... tmpfiles.d

Go Packaging Approaches

Three patterns exist across the project (in upstream junctions):

  1. make + vendored deps in git submodule — simplest when upstream vendors deps (podman, skopeo in freedesktop-sdk)
  2. manual + go_module sources per dep — verbose; one go_module entry per dependency (git-lfs: 33 modules in freedesktop-sdk)
  3. manual + go build with vendored tar — when deps are bundled in a tarball

See the packaging-go-projects skill for step-by-step packaging instructions and helper scripts.

Source Aliases

Defined in include/aliases.yml. Key aliases for Bluefin elements:

AliasExpands ToUsed For
github:https://github.com/git sources
github_files:https://github.com/tarballs, release downloads
gnome:https://gitlab.gnome.org/GNOME/GNOME git sources

Important: Variable substitution (%{go-arch}, etc.) does NOT work in source URLs. Use the multi-arch dispatcher pattern instead.