Skip to content

Repository files navigation

stacks.bits

Defaults and options for building the LCG software stack with bits. This repository ships no package recipes of its own — those live in lcg.bits, a pool of ~1100 recipes. stacks.bits is the policy layer: it declares the compiler/build-type/release options, the CVMFS publish layout, and the package families, and it points every build at the matching lcg.bits branch.

It is designed to reproduce lcgcmake build types and CVMFS installation layout, so if you know lcgcmake, the mapping below should feel familiar.


Table of Contents


Repository Discovery & Provider Model

bits resolves recipes along an ordered search path (BITS_PATH), seeded from bits.rc (search_path) or the environment. Prefferably, beyond local *.bits checkouts and with zero configuration, a repository can be pulled in on demand by a repository-provider package — an ordinary recipe carrying provides_repository: true whose source points at a recipe repo. When bits meets one while scanning dependencies it clones the source into sw/REPOS/<pkg>/<hash>/, adds it to BITS_PATH, and rescans — repeating for nested providers until the graph is stable. Each provider's commit hash is folded into every package's build hash, so bumping a pool triggers a rebuild.

lcg.bits is itself a versioned package. Its provider recipe is just:

package: lcg.bitsversion: "1"tag: "main"# which branch/commit of the recipe pool to cloneprovides_repository: truealways_load: truesource: https://github.com/bitsorg/lcg.bits

stacks.bits does requires: lcg.bits and pins its version with overrides: lcg.bits: tag: "%(release)s" — so the release label selects the exact recipe-pool branch (see Branches and Releases). Groups like key4hep.bits / ship.bits are provider repos too: they can start from their own defaults or reuse this model.


Mapping bits to lcgcmake

lcgcmake conceptbits equivalentWhere it lives
BINARY_TAG = arch-os-comp-buildtypearchitecture string <os>_<machine> + append_arch suffixes, e.g. ubuntu2510_x86-64-gcc15-dbgcompiler/build-type profiles
LCG_COMP / LCG_COMPVERS (gcc13, clang…)defaults-gcc13/14/15, defaults-clang (each append_arch: -gccNN / -clang)this repo
LCG_BUILD_TYPE (opt, dbg, o2g…) → CMAKE_BUILD_TYPEbase sets RELWITHDEBINFO; defaults-dbg sets Debug (append_arch: -dbg)this repo
Release (dev3, dev4, LCG_107) as a path levelthe {release} slot in the CVMFS templatesdefaults-devN / branch / tag
heptools-devN.cmake (version pins for a release)defaults-devNoverrides:this repo
generators/ directory groupingpackage_family: MCGenerators (fnmatch list)defaults-release
/cvmfs/…/lcg/releases/<LCG_VERSION>/[<group>/]<pkg>/<ver>/<platform>…/releases/<release>/<family>/<pkg>/<tag>/<platform>defaults-release templates
LCG_external_package / LCG_AA_project versionrecipe version:/tag: in lcg.bits, overridable per releaselcg.bits + defaults-devN

The defaults-release.sh Profile

defaults-release is the base profile every build inherits. Its top-level keys:

KeyPurposeHashed?
package / versionidentifies the pseudo-package
requireswhat the base pulls in (here: lcg.bits, the recipe pool)yes
env:build environment exported to every package (CXXFLAGS, CFLAGS, CMAKE_BUILD_TYPE, MACOSX_DEPLOYMENT_TARGET, ENABLE_IPO)yes — folded into every package hash, so a flag change yields a distinct, reproducible identity
variables:%(name)s template values used in overrides/recipes — notably releaseindirectly (only through what they expand)
overrides:per-package field overrides (source/tag/version), e.g. lcg.bits: tag: "%(release)s"yes (changes the resolved recipe)
package_family:fnmatch map assigning the {family} path segment (see Package Families)no (a path concern)
system:deployment/policy — see belowno — never folded into package hashes

The system: Block

The system: block holds everything about where and how things build and publish, deliberately kept out of the package hash (the same binary can be published to different paths without changing identity):

system: fieldMeaning
sandbox_networkbuild-sandbox network policy (on/off); recipes may still override per package
build_oversubscribeparallelism factor (e.g. 1.25-j slightly above core count)
prefixthe CVMFS root, e.g. /cvmfs/sft-nightlies-test.cern.ch/lcg
cvmfs_user_prefixroot for per-user (non-admin) publishes: <user_prefix>/<login>
cvmfs_releases_templateper-package publish path (tokens {release},{family},{pkg},{tag},{platform})
cvmfs_modules_templatemodulefile publish path
cvmfs_shared_path_templatenoarch/shared publish path
remote_storethe S3 content store for reuse + upload, e.g. b3://<bucket>::rw (see The S3 Content Store)
certify_groupgroup name stamped into the signed common manifest
manifests_remotegit repo where build/common manifests are recorded

The current templates:

prefix: /cvmfs/sft-nightlies-test.cern.ch/lcg
releases: {prefix}/releases/{release}/{family}{pkg}/{tag}/{platform}
shared: {prefix}/releases/{release}/noarch/{pkg}/{tag}
modules: {prefix}/releases/{release}/{platform}/Modules/modulefiles/{pkg}

{release} collapses out when it is the trunk (main), and {family} collapses for externals — so a plain external on the default line lands at …/releases/<pkg>/<tag>/<platform>, exactly the pre-release layout.

stacks.bits does not set remote_store/certify_group/manifests_remote itself — locally you pass the store on the command line (or ~/.bits/s3keys), and in CI bits-console supplies them as job variables.


Command-Line Usage

Options are composable profiles combined with ::. release is always the implicit base (auto-prepended), so you only name the overlays:

bits build ROOT --defaults gcc15 # release + gcc15 (c++23, RelWithDebInfo)
bits build ROOT --defaults gcc15::dbg # + Debug build type
bits build ROOT --defaults gcc13::dev4 # gcc13, ROOT 6.40 pinned, release "dev4"
bits build ROOT --defaults clang::cuda # clang + CUDA knobs

Composing Profiles

The profiles fall on independent axes, each contributing an append_arch suffix (so the arch string is the bitsBINARY_TAG):

AxisProfilesSetsappend_arch
Compilergcc13, gcc14, gcc15, clangGCC-Toolchain tag (or prefer_system for clang) + the C++ standard in CXXFLAGS-gcc13-clang
Build type(base), dbgCMAKE_BUILD_TYPE = RELWITHDEBINFO / Debug-dbg
FeaturecudaCUDA knobs (never CXXFLAGS)-cuda
Release(base), dev3, dev4the release label + per-package version pins(none — release is a path level, not an arch suffix)

The C++ standard is owned by the compiler axis (gcc13/14 → c++20, gcc15 → c++23, clang → c++20), never by the base or the build-type/feature profiles — so dbg/cuda compose with any compiler without clobbering -std.

Previewing Publish Paths

bits cvmfs-path -c . --defaults <chain> --package <pkg> --version <v> --platform <p> prints the exact publish path a build would use — handy to preview where a chain lands before building.


Branches and Releases

One value — the release label — names three things at once: the CVMFS {release} path slot, the lcg.bits branch to build against (overrides: lcg.bits: tag: "%(release)s"), and the tag stacks.bits will converge to. bits resolves it, highest precedence first:

  1. an explicit, non-trunk release: in the chosen defaults (dev3, dev4, a tagged LCG_107),
  2. else the working-directory branch name (-patches stripped, so LCG_107-patchesLCG_107),
  3. else main — the default: build lcg.bitsmain, and (because main collapses out of the path) publish with no release level (old behaviour).

The effective release must exist as an lcg.bits branch — that branch is the recipe pool. Check out feature-x in your working copy and the build tracks lcg.bitsfeature-x and publishes under …/releases/feature-x/…, isolated from main. dev3/dev4 move the branch and the slot together.


Package Families

bits assigns each package a family via fnmatch on package_family: in defaults-release.sh; the family becomes a path segment (…/releases/<release>/MCGenerators/pythia8/…). There is no default: family, so anything unlisted is an external and its segment collapses out — matching lcgcmake, where a package's home is its directory, not its dependency graph. MCGenerators mirrors lcgcmake's generators/ tree; core/AA packages like ROOT, HepMC, Geant4 stay externals.


Local Development

Building is done with bits; exploring and using the resulting module environment is done with bitsenv, the Environment Modules front-end. A build installs to sw/<arch>/[<family>/]<pkg>/<ver>-<rev>/ and generates a modulefile named <package>/<version> that bitsenv can then load.

Building Packages

Build a single package (work dir defaults to sw, arch auto-detected):

bits build ROOT --defaults gcc15
bits build ROOT --defaults gcc15 -a ubuntu2510_x86-64-gcc15 -w /scratch/sw
bits deps ROOT --defaults gcc15 # inspect the dependency tree first

Using the Module Environment

Discover the built modules:

bitsenv q # list every available module (alias: bitsenv query)
bitsenv q pythia # ...matching a regexp

Test / use a package in its module environment — three ways (bitsenv [-p <platform>] [-m <modules dir>] <verb>):

# a) interactive subshell with the module(s) loaded; `exit` to leave.
bitsenv enter ROOT/v6.38.00
bitsenv enter ROOT/v6.38.00,Geant4/v11.4.1 # several modules, comma-separated# b) run ONE command in the environment (exit code preserved):
bitsenv setenv ROOT/v6.38.00 -c root -b # everything after -c runs as-is# c) inject the environment into your CURRENT shell (note the backticks):eval`bitsenv printenv ROOT/v6.38.00`
bitsenv checkenv ROOT/v6.38.00 # sanity-check the module env

Building the Full Stack

Build the full stack via the meta-packages in this repo — they pull in the whole set as dependencies:

bits build externals --defaults gcc15 # libraries, tools, Python, ML, core
bits build generators --defaults gcc15 # event generators (MCGenerators family)

Iteration Workflow

Iterate: edit a recipe in lcg.bits on a branch, re-run bits build (only what changed rebuilds — see The S3 Content Store on reuse), and bits clean to reset the build area. Because the local install tree already carries the family/arch layout, what you test locally is exactly what gets published.


The S3 Content Store & Certification

Three artefacts, deliberately separate:

  • S3 content store — a content-addressed cache of build tarballs (TARS/<arch>/store/<hash>/…, hash-only). Identical inputs → identical hash → identical binary, so any builder can reuse a prebuilt package instead of rebuilding. This is why the store exists: it makes builds fast and reproducible across machines and CI, and it's the substrate certification trusts. Configured via system.remote_store (b3://<bucket>::rw); credentials in ~/.bits/s3keys (or $BITS_AWS_KEYS_FILE), store override $BITS_S3_STORE.
  • CVMFS release tree — the path-addressed deployment users actually mount (…/releases/<release>/<family>/<pkg>/<tag>/<platform>).
  • Signed common manifest — the trust unit: what a client verifies before reusing a binary.

Reuse happens automatically at build time: for each dependency bits resolves a hash and, if that object is already in the store (from_remote_store, with --check-store), downloads it rather than building. A finished build uploads its tarball for the next consumer. (bits build --reuse-policy relaxed --reuse-base <build_id> can graft a deployed release's binaries.)

bits build <pkg># checks the store, builds only what's missing, uploads results
bits publish <pkg># relocates the install to its CVMFS path and streams it# to the ingestion spool → the release tree
bits certify … # merges published build manifests into ONE common manifest,# validates every content hash against the S3 store, and# signs it with the release Ed25519 key (clients trust this)

certify is what turns a pile of uploaded tarballs into something safe to reuse: it checks each hash really is in the store and signs the result. certify_group, manifests_remote (and the release key) configure it.

Store Inspection & Management

Inspect / verify / clean the store with bits store:

bits store ls --arch A --group G --package P --version V # list (manifest-aware selection)
bits store verify [--arch A] [--deep] [--orphans] # integrity check vs manifests
bits store rm <selection> [-n] # delete (e.g. --orphans, --expired); -n dry-run
bits gc # reachability GC: roots = hashes in the# verified signed manifest; fail-closed

Normally you don't run publish/certify by hand — the bits-console cvmfs-prepub pipeline does it (see CI Pipelines). Locally you mostly build + enter/setenv to test, and use bits store to inspect what reuse will pull.


CI Pipelines

A commit to lcg.bitsorstacks.bits (including a GitLab pull-mirror sync) can fire a designated pipeline configured and saved in bits-console, giving nightly/CI-style rebuilds without redefining the build here.

  • The build definition (packages, platforms, defaults chain, providers, publish/certify) is authored in the console's Build modal → "Save as pipeline" and stored at communities/<GROUP>/pipelines/<PIPELINE>.json.
  • A small .gitlab-ci.yml in the recipe repo only fires it. lcg.bits ships one that multi-project-triggers bits-console with BITS_GROUP: LCG, BITS_PIPELINE: on-commit; the downstream run-group-pipeline job fans out one cvmfs-prepub build (build → publish → certify) per enabled entry. stacks.bits can carry an analogous file.

One-time setup (GitLab UI):

  1. bits-console → Settings → CI/CD → Token Access → add the recipe project to the CI_JOB_TOKEN allowlist.
  2. If the recipe repo is a pull-mirror, enable Mirroring → "Trigger pipelines for mirror updates" (the .gitlab-ci.yml must be on the mirrored branch).
  3. In the console, build the stack in the Build modal, tick the options, and Save as pipeline, naming it to match BITS_PIPELINE.

The same saved pipeline can also run on a schedule (nightly) or on demand from the console — the commit trigger is just one entry point.


Files Overview

FileRole
defaults-release.shbase: system: (paths/store/policy), env:, release label, package_family, requires lcg.bits
defaults-gcc13/14/15.sh, defaults-clang.shcompiler axis (toolchain tag + C++ standard)
defaults-dbg.shDebug build type
defaults-cuda.shCUDA feature knobs
defaults-dev3.sh, defaults-dev4.shrelease lines: release label + heptools-devN version pins
externals.sh, generators.shmeta-packages that pull in the externals / generator sets

About

LCG stacks

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages