Supply chain: SBOM and the LLVM version lock

Two related release-mechanics concerns: what a release artifact is made of (the SBOM), and why the LLVM/MLIR major version it links against is pinned (the version lock).

SBOM

Every build emits a CycloneDX 1.5 SBOM describing the release artifacts.

  • Generated by: cmake/GenerateSBOM.cmake, driven by the sbom target, which is part of ALL.
  • Build tree: <build>/llvm-dsdl-sbom.cdx.json
  • Installed to: <prefix>/<datadir>/llvm-dsdl/llvm-dsdl-sbom.cdx.json (component bin)
  • Regenerate on demand: cmake --build <build> --target sbom

Contents

Component Scope Why
llvm-dsdl (metadata component) Tool version (from VERSION), MIT, the shipped tool names, and the exact source commit under pedigree.commits
llvm, mlir required The LLVM/MLIR actually found by find_package and linked into the tools
zstd required (when found) Pulled in transitively by LLVM
llvm-dsdl-runtime required First-party serialization runtime shipped as headers/sources alongside generated code
public_regulated_data_types, libudpard excluded Submodules pinned to exact commits. They are build/test inputs (the DSDL corpus; libudpard for the examples) and are not linked into shipped artifacts — recorded for provenance, scoped out of the shipped dependency set

Determinism

The generator emits no wall-clock timestamp and no random serial number, so regenerating from the same commit produces a byte-identical document. For a timestamped document, pass -DSOURCE_DATE_EPOCH_VALUE=<epoch> to the generator.

If the source tree is not a git checkout (e.g. an extracted tarball), the SBOM is still valid — the commit is recorded as unknown and submodule entries are omitted.

LLVM version lock

Policy: the LLVM/MLIR major version is locked (currently 22).

Why

The C backend is routed through MLIR/EmitC, whose printed output can legitimately vary across MLIR majors. The same DSDL compiled against two different MLIR majors may produce C that differs textually while remaining semantically equivalent, which makes the LLVM major a semantic input to the output rather than a build detail.

Where it is enforced

The lock is enforced at configure time by the build system and again by CI.

  • Build system: after find_package(LLVM/MLIR), CMake asserts LLVM_VERSION_MAJOR equals LLVMDSDL_REQUIRED_LLVM_MAJOR (currently 22) and fails configuration otherwise. -DLLVMDSDL_ALLOW_LLVM_MAJOR_MISMATCH=ON downgrades the failure to a warning. MLIR ships with LLVM at the same version, so asserting the LLVM major covers MLIR too.
  • Linux (x86-64, libstdc++): LLVM_DIR/MLIR_DIR/CMAKE_PREFIX_PATH pin /usr/lib/llvm-22, and the determinism job records the real version via llvm-config --version into the corpus-hash manifest (--meta llvm=…).
  • macOS (arm64, libc++): Homebrew llvm@22, with an asserted major.
  • Cross-stdlib determinism lane: tools/determinism/cross_stdlib_corpus_hash.py compares the two hosts' recorded LLVM majors. CI passes --require-c, which makes a major skew a hard failure.

Consequences

  • Build against the locked major to reproduce released artifacts byte-for-byte.
  • The SBOM records the LLVM/MLIR version actually linked.
  • To raise the lock: bump LLVMDSDL_REQUIRED_LLVM_MAJOR and the CI pins together (both hosts must move at once, or --require-c fails), then re-baseline the determinism corpus hashes.