terranox-bootstrap
SPDX-License-Identifier: Apache-2.0
Installation
dagger install github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948dbEntrypoint
Return Type
TerranoxBootstrap Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
func (m *MyModule) Example() *dagger.TerranoxBootstrap {
return dag.
Terranoxbootstrap()
}@function
def example() -> dagger.TerranoxBootstrap:
return (
dag.terranox_bootstrap()
)@func()
example(): TerranoxBootstrap {
return dag
.terranoxBootstrap()
}Types
TerranoxBootstrap 🔗
TerranoxBootstrap is the main module for the TerranoxOS toolchain pipeline.
aggregateSboms() 🔗
AggregateSboms builds the terranox-sbom-aggregate tool and generates a system-wide SBOM by discovering and merging all CycloneDX SBOMs from the Terranox Store and active strata.
This function: 1. Builds the terranox-sbom-aggregate static binary 2. Discovers all .forge/sbom.cdx.json files in the store 3. Merges them into a single system-wide SBOM 4. Returns the aggregated SBOM as system.cdx.json
The resulting SBOM provides a complete bill of materials for the entire system, including all packages and their dependencies.
Example usage:
# Generate system-wide SBOM from /forge/store
dagger call aggregate-sboms --source=. --store=./mock-store export --path=./system.cdx.json
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing the crates/ directory |
| store | Directory ! | - | Store directory containing packages with .forge/sbom.cdx.json files |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
aggregate-sboms --source DIR_PATH --store DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory, store *dagger.Directory) *dagger.File {
return dag.
Terranoxbootstrap().
Aggregatesboms(source, store)
}@function
def example(source: dagger.Directory, store: dagger.Directory) -> dagger.File:
return (
dag.terranox_bootstrap()
.aggregatesboms(source, store)
)@func()
example(source: Directory, store: Directory): File {
return dag
.terranoxBootstrap()
.aggregateSboms(source, store)
}apkoBuild() 🔗
ApkoBuild assembles an OCI container image from an apko YAML config.
This is the core of the “musl Wolfi” story: apko declaratively assembles an image from Alpine apk packages (all musl-linked), producing a minimal, reproducible OCI image with no runtime build dependencies.
The config file lives in derivations/apko/ and follows apko’s YAML format. Custom melange-built packages can be included by providing a local repository directory.
Usage:
# Build the musl SDK image from the default config:
dagger call apko-build --source=.
# Build with custom apko config:
dagger call apko-build --source=. --config=derivations/apko/sdk-musl.yaml
# Build with local melange packages included:
dagger call apko-build --source=. --local-repo=./packages/x86_64
# Export OCI tarball:
dagger call apko-build --source=. export --path=./terranox-sdk.tar
# Interactive shell:
dagger call apko-build --source=. terminal
Return Type
Container !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory containing derivations/apko/ and packages/ |
| config | String ! | "derivations/apko/sdk-musl.yaml" | Path to apko YAML config within source (relative to repo root) |
| tag | String ! | "terranox-sdk:latest" | Tag for the built image |
| localRepo | Directory | - | Local apk repository directory with melange-built packages. If provided, it is mounted as an additional repository so custom packages can be referenced in the apko config. |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
apko-build --source DIR_PATH --config string --tag stringfunc (m *MyModule) Example(source *dagger.Directory, config string, tag string) *dagger.Container {
return dag.
Terranoxbootstrap().
Apkobuild(source, config, tag)
}@function
def example(source: dagger.Directory, config: str, tag: str) -> dagger.Container:
return (
dag.terranox_bootstrap()
.apkobuild(source, config, tag)
)@func()
example(source: Directory, config: string, tag: string): Container {
return dag
.terranoxBootstrap()
.apkoBuild(source, config, tag)
}apkoBuildSecure() 🔗
ApkoBuildSecure builds an apko image with full security attestation: CycloneDX SBOM, cosign signature, and SLSA provenance.
This is the production entry point for building distributable SDK images. It runs the apko build, collects the native SBOM, signs the tarball, and generates SLSA v1.0 provenance — all in one pipeline.
Output structure:
image.tar - OCI image tarball
image.tar.sha256 - SHA256 digest
image.tar.sig - Cosign signature (placeholder for local, real in CI)
image.tar.bundle - Cosign signature bundle
sbom.cdx.json - CycloneDX SBOM (from apko provenance.json - SLSA v1.0 provenance attestation
Usage:
dagger call apko-build-secure --source=. export --path=./out/sdk-secure
dagger call apko-build-secure --source=. --git-commit=$(git rev-parse HEAD) export --path=./out/sdk-secure
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory containing derivations/apko/ and packages/ |
| config | String ! | "derivations/apko/sdk-musl.yaml" | Path to apko YAML config within source |
| tag | String ! | "terranox-sdk:latest" | Tag for the built image |
| gitCommit | String | - | Git commit hash (for provenance; auto-detected in CI) |
| localRepo | Directory | - | Local apk repository with melange-built packages |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
apko-build-secure --source DIR_PATH --config string --tag stringfunc (m *MyModule) Example(source *dagger.Directory, config string, tag string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Apkobuildsecure(source, config, tag)
}@function
def example(source: dagger.Directory, config: str, tag: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.apkobuildsecure(source, config, tag)
)@func()
example(source: Directory, config: string, tag: string): Directory {
return dag
.terranoxBootstrap()
.apkoBuildSecure(source, config, tag)
}apkoPublish() 🔗
ApkoPublish builds an apko image and publishes it to a container registry.
Usage:
dagger call apko-publish --source=. --registry=ghcr.io/terranox-os/sdk:latest
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
| registry | String ! | - | Full registry address (e.g., ghcr.io/terranox-os/sdk:latest) |
| config | String ! | "derivations/apko/sdk-musl.yaml" | Path to apko YAML config within source |
| localRepo | Directory | - | Local apk repository with melange-built packages |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
apko-publish --source DIR_PATH --registry string --config stringfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, registry string, config string) string {
return dag.
Terranoxbootstrap().
Apkopublish(ctx, source, registry, config)
}@function
async def example(source: dagger.Directory, registry: str, config: str) -> str:
return await (
dag.terranox_bootstrap()
.apkopublish(source, registry, config)
)@func()
async example(source: Directory, registry: string, config: string): Promise<string> {
return dag
.terranoxBootstrap()
.apkoPublish(source, registry, config)
}applyTerranoxPatches() 🔗
ApplyTerranoxPatches applies TerranoxOS-specific patches to LLVM source. These patches add x86_64-pc-terranox triple support.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmSrc | Directory ! | - | LLVM source directory |
| patches | Directory ! | - | Patch directory from the repository |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
apply-terranox-patches --llvm-src DIR_PATH --patches DIR_PATHfunc (m *MyModule) Example(llvmSrc *dagger.Directory, patches *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Applyterranoxpatches(llvmSrc, patches)
}@function
def example(llvmsrc: dagger.Directory, patches: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.applyterranoxpatches(llvmsrc, patches)
)@func()
example(llvmSrc: Directory, patches: Directory): Directory {
return dag
.terranoxBootstrap()
.applyTerranoxPatches(llvmSrc, patches)
}base() 🔗
Base returns a Wolfi container with the seed LLVM/Clang toolchain and all build dependencies installed. This is the foundation every other function builds on.
Return Type
Container ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
basefunc (m *MyModule) Example() *dagger.Container {
return dag.
Terranoxbootstrap().
Base()
}@function
def example() -> dagger.Container:
return (
dag.terranox_bootstrap()
.base()
)@func()
example(): Container {
return dag
.terranoxBootstrap()
.base()
}bootstrap() 🔗
Bootstrap runs the full pipeline: validate → stage0 → sysroot → stage1. Returns a directory with the complete toolchain.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
bootstrap --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Bootstrap(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.bootstrap(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.bootstrap(llvmVersion)
}bootstrapBaseImage() 🔗
BootstrapBaseImage builds the core melange packages and assembles them into a minimal TerranoxOS base image via apko.
This is the path to replacing alpine:3.19 — once this image exists, subsequent melange builds can use it as the build host instead of Alpine.
Phase 1 (current): Build what we can from source, pull the rest from Alpine. Phase 2 (future): All packages from TerranoxOS melange repo.
Core packages built from source: - musl (C library) - busybox (shell - zlib (compression) - openssl (TLS/crypto) - ca-certificates (root CA bundle) - apk-tools (package manager)
Usage:
# Build base image:
dagger call bootstrap-base-image --source=. export --path=./terranox-base.tar
# Build base image with security attestation:
dagger call bootstrap-base-image --source=. --secure export --path=./out/base
For self-hosted builds where earlier packages feed into later ones, use SelfHostBuild instead.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory containing derivations/ and packages/ |
| secure | Boolean ! | false | Enable security attestation (SBOM + signing |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
bootstrap-base-image --source DIR_PATH --secure booleanfunc (m *MyModule) Example(source *dagger.Directory, secure bool) *dagger.Directory {
return dag.
Terranoxbootstrap().
Bootstrapbaseimage(source, secure)
}@function
def example(source: dagger.Directory, secure: bool) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.bootstrapbaseimage(source, secure)
)@func()
example(source: Directory, secure: boolean): Directory {
return dag
.terranoxBootstrap()
.bootstrapBaseImage(source, secure)
}bootstrapWithSecurity() 🔗
BootstrapWithSecurity runs the full bootstrap pipeline and generates all security artifacts.
This function: 1. Runs Bootstrap() to build the complete toolchain 2. Generates CycloneDX SBOM 3. Signs the toolchain with Cosign 4. Generates SLSA Build Level 3 provenance 5. Returns a directory with toolchain + all security attestations
Output directory structure:
/toolchain/ - Complete toolchain (tools /security/
sbom.cdx.json - CycloneDX SBOM
build-manifest.json - Build metadata
toolchain.tar.gz - Signed toolchain tarball
toolchain.tar.gz.sha256 - SHA256 digest
toolchain.tar.gz.sig - Cosign signature
toolchain.tar.gz.bundle - Cosign signature bundle
provenance.json - SLSA provenance attestation
Example usage:
# Bootstrap with full security attestation:
dagger call bootstrap-with-security --llvm-version=21.1.8 export --path=./terranox-toolchain
# Verify security artifacts:
dagger call verify-security-attestation --artifacts ./terranox-toolchain/security
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | LLVM version to build |
| source | Directory | - | Repository source directory containing patches/ |
| gitCommit | String | - | Git commit hash (for provenance tracking in CI) |
| variant | String ! | "musl" | Toolchain variant: “musl” or “glibc” |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
bootstrap-with-security --llvm-version string --variant stringfunc (m *MyModule) Example(llvmVersion string, variant string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Bootstrapwithsecurity(llvmVersion, variant)
}@function
def example(llvmversion: str, variant: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.bootstrapwithsecurity(llvmversion, variant)
)@func()
example(llvmVersion: string, variant: string): Directory {
return dag
.terranoxBootstrap()
.bootstrapWithSecurity(llvmVersion, variant)
}buildCoreSystem() 🔗
BuildCoreSystem builds the complete /core base system structure with all statically-linked binaries and configuration files required for v0.1.0.
The /core directory is the immutable base layer containing: - Static bash shell - Static busybox (coreutils) - terranox-strata activation tool - terranox-init wrapper - System configuration files
All binaries are statically linked with musl to ensure zero libc dependency, making /core agnostic to which libc the active strata use.
Returns a complete /core directory ready for installation.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing the TerranoxOS repository |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
build-core-system --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Buildcoresystem(source)
}@function
def example(source: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.buildcoresystem(source)
)@func()
example(source: Directory): Directory {
return dag
.terranoxBootstrap()
.buildCoreSystem(source)
}buildDeveloperStratum() 🔗
BuildDeveloperStratum builds a mock developer stratum with placeholder binaries for testing the strata activation system in v0.1.0.
This creates a /strata/developer/ directory structure with: - Mock binaries (clang, vim, git, make, cmake, llvm-*) - Placeholder man pages - Shell scripts that identify themselves when executed
For v0.1.0, these are just mock binaries to test activation. Real packages will come from the Forge store in later versions.
Returns a complete /strata/developer/ directory ready for activation.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing the TerranoxOS repository (for manifest) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
build-developer-stratum --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Builddeveloperstratum(source)
}@function
def example(source: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.builddeveloperstratum(source)
)@func()
example(source: Directory): Directory {
return dag
.terranoxBootstrap()
.buildDeveloperStratum(source)
}buildInitramfs() 🔗
BuildInitramfs builds the initial RAM filesystem (initramfs) that the kernel loads at boot time before mounting the real root filesystem.
The initramfs contains: - /init script - Early boot initialization (mounts filesystems, runs strata activation) - Static busybox - Provides mount, switch_root, sh, and basic utilities - Static terranox-strata - Activates strata and creates FHS symlinks
Boot sequence: 1. Kernel loads initramfs into RAM 2. Kernel executes /init 3. /init mounts /proc, /sys, /dev 4. /init mounts real root filesystem 5. /init mounts /core (ro), /strata (ro), /forge (ro), /state (rw,noexec), /user (rw) 6. /init runs terranox-strata activate (creates FHS symlinks at /) 7. /init calls switch_root to pivot to real root 8. /init execs /core/usr/bin/terranox-init (which execs dinit as PID 1)
Returns a compressed initramfs.cpio.gz file ready for bootloader.
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing the TerranoxOS repository |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
build-initramfs --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.File {
return dag.
Terranoxbootstrap().
Buildinitramfs(source)
}@function
def example(source: dagger.Directory) -> dagger.File:
return (
dag.terranox_bootstrap()
.buildinitramfs(source)
)@func()
example(source: Directory): File {
return dag
.terranoxBootstrap()
.buildInitramfs(source)
}buildRootFs() 🔗
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing the TerranoxOS repository |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
build-root-fs --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Buildrootfs(source)
}@function
def example(source: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.buildrootfs(source)
)@func()
example(source: Directory): Directory {
return dag
.terranoxBootstrap()
.buildRootFs(source)
}buildStrata() 🔗
BuildStrata builds the terranox-strata system state manager as a statically-linked binary for /core integration.
The binary is built with: - Rust toolchain from Alpine - x86_64-unknown-linux-musl target (static linking) - Release optimizations - llvm-strip for size reduction
Returns a static ELF binary ready for deployment to /core/usr/bin/
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing the crates/ directory |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
build-strata --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.File {
return dag.
Terranoxbootstrap().
Buildstrata(source)
}@function
def example(source: dagger.Directory) -> dagger.File:
return (
dag.terranox_bootstrap()
.buildstrata(source)
)@func()
example(source: Directory): File {
return dag
.terranoxBootstrap()
.buildStrata(source)
}buildToolchainImage() 🔗
BuildToolchainImage builds the 3-stage musl toolchain as separate melange packages, then assembles a container image via apko.
Each stage is an independent melange package with its own cache:
Stage 0: terranox-stage0 (cross-compiler, ~20 min)
Sysroot: terranox-sysroot (musl + LLVM runtimes, ~10 min)
Stage 1: terranox-clang (self-hosted compiler, ~20 min)
If Stage 0 succeeds but Sysroot fails, Stage 0 is cached and won’t rebuild. Pre-built APK repos can be passed in to skip any/all stages.
Usage:
# Full pipeline from scratch:
dagger call build-toolchain-image --source=. export --path=./terranox-toolchain.tar
# Skip Stage 0 (already built):
dagger call build-toolchain-image --source=. --stage0-repo=./out/stage0
# Skip everything, just assemble image:
dagger call build-toolchain-image --source=. --apk-repo=./out/all-packages
# Interactive shell:
dagger call build-toolchain-image --source=. terminal
Return Type
Container !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory containing derivations/ and packages/ |
| stage0Repo | Directory | - | Pre-built Stage 0 APK repo. If provided, skips Stage 0 build. |
| sysrootRepo | Directory | - | Pre-built Sysroot APK repo. If provided, skips Sysroot build. |
| apkRepo | Directory | - | Pre-built APK repo with all packages (stage0 + sysrootIf provided, skips all builds and goes straight to image assembly. |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
build-toolchain-image --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.Container {
return dag.
Terranoxbootstrap().
Buildtoolchainimage(source)
}@function
def example(source: dagger.Directory) -> dagger.Container:
return (
dag.terranox_bootstrap()
.buildtoolchainimage(source)
)@func()
example(source: Directory): Container {
return dag
.terranoxBootstrap()
.buildToolchainImage(source)
}creusotProve() 🔗
CreusotProve runs Creusot verification on Rust source code.
Usage:
dagger call creusot-prove --source=./crates/world-core --file=src/store.rs
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing Rust crate |
| file | String ! | - | Rust file to verify (relative to source) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
creusot-prove --source DIR_PATH --file stringfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, file string) string {
return dag.
Terranoxbootstrap().
Creusotprove(ctx, source, file)
}@function
async def example(source: dagger.Directory, file: str) -> str:
return await (
dag.terranox_bootstrap()
.creusotprove(source, file)
)@func()
async example(source: Directory, file: string): Promise<string> {
return dag
.terranoxBootstrap()
.creusotProve(source, file)
}diagnoseSysroot() 🔗
TestStage1Build verifies Stage1 self-hosted compiler builds and works. Stage1 is the final production compiler linked against musl + LLVM runtimes.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory ! | - | No description provided |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
diagnose-sysroot --llvm-version string --musl-version string --linux-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, muslVersion string, linuxVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Diagnosesysroot(ctx, llvmVersion, muslVersion, linuxVersion, source)
}@function
async def example(llvmversion: str, muslversion: str, linuxversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.diagnosesysroot(llvmversion, muslversion, linuxversion, source)
)@func()
async example(llvmVersion: string, muslVersion: string, linuxVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.diagnoseSysroot(llvmVersion, muslVersion, linuxVersion, source)
}export() 🔗
Export builds the toolchain and writes it to the host filesystem.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| output | Directory ! | - | Host directory to export to |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
export --llvm-version string --output DIR_PATHfunc (m *MyModule) Example(llvmVersion string, output *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Export(llvmVersion, output)
}@function
def example(llvmversion: str, output: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.export(llvmversion, output)
)@func()
example(llvmVersion: string, output: Directory): Directory {
return dag
.terranoxBootstrap()
.export(llvmVersion, output)
}exportSbom() 🔗
ExportSBOM generates SBOM and exports to standard artifact location. This is a convenience wrapper around GenerateSBOM that follows the artifact storage convention: /build/artifacts/{component}-{version}/sbom.cdx.json
Usage:
# Export Stage1 SBOM to standard location:
dagger call export-sbom --toolchain $(dagger call stage-1) --llvm-version=21.1.8
# Also creates build-manifest.json in the same directory
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built toolchain directory (output of Stage1) If not provided, will build Stage1 automatically |
| llvmVersion | String ! | "21.1.8" | No description provided |
| libcVersion | String ! | "1.2.5" | C library version (musl or glibc depending on variant) |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
| component | String ! | "stage1-llvm" | Component name for artifact directory (e.g., “stage1-llvm”, “gnat-llvm”) |
| variant | String ! | "musl" | Toolchain variant: “musl” or “glibc” |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
export-sbom --llvm-version string --libc-version string --linux-version string --component string --variant stringfunc (m *MyModule) Example(llvmVersion string, libcVersion string, linuxVersion string, component string, variant string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Exportsbom(llvmVersion, libcVersion, linuxVersion, component, variant)
}@function
def example(llvmversion: str, libcversion: str, linuxversion: str, component: str, variant: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.exportsbom(llvmversion, libcversion, linuxversion, component, variant)
)@func()
example(llvmVersion: string, libcVersion: string, linuxVersion: string, component: string, variant: string): Directory {
return dag
.terranoxBootstrap()
.exportSbom(llvmVersion, libcVersion, linuxVersion, component, variant)
}exportSdkSysroot() 🔗
ExportSdkSysroot builds the SDK sysroot and writes it to the host filesystem.
Usage:
dagger call export-sdk-sysroot --llvm-version=21.1.8 --source=. --output=./out/sdk-sysroot
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| output | Directory ! | - | Host directory to export to |
| source | Directory | - | Repository source directory containing patches/ and bootstrap.toml |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
export-sdk-sysroot --llvm-version string --output DIR_PATHfunc (m *MyModule) Example(llvmVersion string, output *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Exportsdksysroot(llvmVersion, output)
}@function
def example(llvmversion: str, output: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.exportsdksysroot(llvmversion, output)
)@func()
example(llvmVersion: string, output: Directory): Directory {
return dag
.terranoxBootstrap()
.exportSdkSysroot(llvmVersion, output)
}fetchGlibc() 🔗
FetchGlibc downloads and extracts a specific version of glibc. Returns the extracted source directory.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| version | String ! | "2.39" | No description provided |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
fetch-glibc --version stringfunc (m *MyModule) Example(version string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Fetchglibc(version)
}@function
def example(version: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.fetchglibc(version)
)@func()
example(version: string): Directory {
return dag
.terranoxBootstrap()
.fetchGlibc(version)
}fetchLlvm() 🔗
FetchLLVM returns a directory containing the LLVM source tree for the specified version. “main” clones git trunk; anything else downloads the release tarball.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| version | String ! | "21.0.0" | LLVM version: “main” for git trunk, or a release like “21.0.0” |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
fetch-llvm --version stringfunc (m *MyModule) Example(version string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Fetchllvm(version)
}@function
def example(version: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.fetchllvm(version)
)@func()
example(version: string): Directory {
return dag
.terranoxBootstrap()
.fetchLlvm(version)
}fetchLinuxHeaders() 🔗
FetchLinuxHeaders returns installed kernel headers as a directory.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| version | String ! | "6.12.8" | No description provided |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
fetch-linux-headers --version stringfunc (m *MyModule) Example(version string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Fetchlinuxheaders(version)
}@function
def example(version: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.fetchlinuxheaders(version)
)@func()
example(version: string): Directory {
return dag
.terranoxBootstrap()
.fetchLinuxHeaders(version)
}fetchMusl() 🔗
FetchMusl returns the musl source directory.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| version | String ! | "1.2.5" | No description provided |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
fetch-musl --version stringfunc (m *MyModule) Example(version string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Fetchmusl(version)
}@function
def example(version: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.fetchmusl(version)
)@func()
example(version: string): Directory {
return dag
.terranoxBootstrap()
.fetchMusl(version)
}framaCprove() 🔗
FramaCProve runs Frama-C WP verification on a C source file.
Usage:
dagger call frama-c-prove --source=./kernel/core --file=pmm.c
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing C files |
| file | String ! | - | C file to verify (relative to source) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
frama-cprove --source DIR_PATH --file stringfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, file string) string {
return dag.
Terranoxbootstrap().
Framacprove(ctx, source, file)
}@function
async def example(source: dagger.Directory, file: str) -> str:
return await (
dag.terranox_bootstrap()
.framacprove(source, file)
)@func()
async example(source: Directory, file: string): Promise<string> {
return dag
.terranoxBootstrap()
.framaCprove(source, file)
}generateProvenance() 🔗
GenerateProvenance generates SLSA Build Level 3 provenance for the toolchain.
This creates a provenance attestation following the SLSA v1.0 specification, documenting the build process, materials, and outputs.
Example usage:
# Generate provenance for toolchain:
dagger call generate-provenance --toolchain $(dagger call stage-1) export --path=./provenance.json
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built toolchain directory (output of Stage1) If not provided, will build Stage1 automatically |
| llvmVersion | String ! | "21.1.8" | LLVM version to use |
| libcVersion | String ! | "1.2.5" | C library version |
| linuxVersion | String ! | "6.12.8" | Linux kernel headers version |
| source | Directory | - | Repository source directory containing patches/ |
| gitCommit | String | - | Git commit hash (for CI builds) |
| buildTimestamp | String | - | Build timestamp (ISO 8601 format) |
| variant | String ! | "musl" | Toolchain variant: “musl” or “glibc” |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
generate-provenance --llvm-version string --libc-version string --linux-version string --variant stringfunc (m *MyModule) Example(llvmVersion string, libcVersion string, linuxVersion string, variant string) *dagger.File {
return dag.
Terranoxbootstrap().
Generateprovenance(llvmVersion, libcVersion, linuxVersion, variant)
}@function
def example(llvmversion: str, libcversion: str, linuxversion: str, variant: str) -> dagger.File:
return (
dag.terranox_bootstrap()
.generateprovenance(llvmversion, libcversion, linuxversion, variant)
)@func()
example(llvmVersion: string, libcVersion: string, linuxVersion: string, variant: string): File {
return dag
.terranoxBootstrap()
.generateProvenance(llvmVersion, libcVersion, linuxVersion, variant)
}generateReleaseNotes() 🔗
GenerateReleaseNotes generates changelog and release notes from git history.
Usage:
dagger call generate-release-notes --source=. --version=0.2.0 --previous=0.1.0
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
| version | String ! | - | New version being released |
| previousVersion | String ! | - | Previous version for comparison |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
generate-release-notes --source DIR_PATH --version string --previous-version stringfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, version string, previousVersion string) string {
return dag.
Terranoxbootstrap().
Generatereleasenotes(ctx, source, version, previousVersion)
}@function
async def example(source: dagger.Directory, version: str, previousversion: str) -> str:
return await (
dag.terranox_bootstrap()
.generatereleasenotes(source, version, previousversion)
)@func()
async example(source: Directory, version: string, previousVersion: string): Promise<string> {
return dag
.terranoxBootstrap()
.generateReleaseNotes(source, version, previousVersion)
}generateSbom() 🔗
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built toolchain directory (output of Stage1) If not provided, will build Stage1 automatically |
| llvmVersion | String ! | "21.1.8" | No description provided |
| libcVersion | String ! | "1.2.5" | C library version (musl or glibc depending on variant) |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
| variant | String ! | "musl" | Toolchain variant: “musl” or “glibc” |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
generate-sbom --llvm-version string --libc-version string --linux-version string --variant stringfunc (m *MyModule) Example(llvmVersion string, libcVersion string, linuxVersion string, variant string) *dagger.File {
return dag.
Terranoxbootstrap().
Generatesbom(llvmVersion, libcVersion, linuxVersion, variant)
}@function
def example(llvmversion: str, libcversion: str, linuxversion: str, variant: str) -> dagger.File:
return (
dag.terranox_bootstrap()
.generatesbom(llvmversion, libcversion, linuxversion, variant)
)@func()
example(llvmVersion: string, libcVersion: string, linuxVersion: string, variant: string): File {
return dag
.terranoxBootstrap()
.generateSbom(llvmVersion, libcVersion, linuxVersion, variant)
}glibcBootstrap() 🔗
GlibcBootstrap builds the complete glibc-based toolchain and packages it into a single output directory with a manifest.
Pre-built Stage0 and Sysroot can be passed in to skip rebuilding. This enables incremental CI where earlier stages are cached as artifacts between jobs.
Pipeline:
Wolfi seed ──→ Stage0 (cross-compiler)
Wolfi seed ──→ Sysroot (glibc + LLVM runtimes)
Stage0 + Sysroot ──→ Stage1 (self-hosted glibc Clang)
Output structure:
tools/ - Stage1 Clang, LLD, llvm-ar, etc.
sysroot/ - glibc headers/libs, LLVM runtimes, kernel headers
manifest.json - Build metadata
Usage:
dagger call glibc-bootstrap
dagger call glibc-bootstrap --stage0=./cached-stage0 --sysroot=./cached-sysroot
dagger call glibc-bootstrap export --path=./toolchain
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| stage0 | Directory | - | Pre-built Stage0 cross-tools directory. Skips Stage0 build if provided. |
| sysroot | Directory | - | Pre-built sysroot directory. Skips sysroot build if provided. |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
glibc-bootstrap --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Glibcbootstrap(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.glibcbootstrap(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.glibcBootstrap(llvmVersion)
}glibcStage0() 🔗
GlibcStage0 builds the Stage 0 cross-compiler for the glibc variant: a Clang targeting x86_64-pc-terranox-gnu. Built in Wolfi (glibc-based) so all build tools are glibc-linked.
Host: Wolfi (glibc) Seed: Wolfi’s Clang Output: /opt/terranox-glibc/cross-tools (Clang + LLD targeting glibc)
Usage:
dagger call glibc-stage0
dagger call glibc-stage0 --llvm-version=21.1.8
dagger call glibc-stage0 export --path=./stage0
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
glibc-stage-0 --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Glibcstage0(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.glibcstage0(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.glibcStage0(llvmVersion)
}glibcStage1() 🔗
GlibcStage1 builds the self-hosted Clang linked against glibc. This is the final compiler for the glibc variant with zero GNU dependencies.
Host: Wolfi (glibc) Compiler: Stage0 cross-compiler (built or pre-built) Links against: Sysroot (glibc + LLVM runtimes, built or pre-built) Output: /opt/terranox-glibc/tools (self-hosted Clang Pre-built Stage0 and Sysroot can be passed in to skip rebuilding:
dagger call glibc-stage1 --stage0=./cached-stage0 --sysroot=./cached-sysroot
dagger call glibc-stage1 export --path=./stage1
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| glibcVersion | String ! | "2.41" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| stage0 | Directory | - | Pre-built Stage0 cross-tools directory. If not provided, Stage0 is built from scratch. |
| sysroot | Directory | - | Pre-built sysroot directory. If not provided, the sysroot is built from scratch. |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
glibc-stage-1 --llvm-version string --glibc-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, glibcVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Glibcstage1(llvmVersion, glibcVersion, linuxVersion)
}@function
def example(llvmversion: str, glibcversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.glibcstage1(llvmversion, glibcversion, linuxversion)
)@func()
example(llvmVersion: string, glibcVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.glibcStage1(llvmVersion, glibcVersion, linuxVersion)
}glibcSysroot() 🔗
GlibcSysroot builds the glibc variant sysroot containing: - glibc (C standard library) - Linux kernel headers - LLVM runtimes (compiler-rt, libunwind, libc++abi, libc Host: Wolfi (glibc) — consistent with GlibcStage0 and GlibcStage1. Wolfi’s native Clang builds glibc directly since both the host and target are glibc.
Usage:
dagger call glibc-sysroot
dagger call glibc-sysroot export --path=./sysroot
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | LLVM version to build runtimes from |
| glibcVersion | String ! | "2.41" | glibc version |
| linuxVersion | String ! | "6.12.8" | Linux kernel version for headers |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
glibc-sysroot --llvm-version string --glibc-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, glibcVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Glibcsysroot(llvmVersion, glibcVersion, linuxVersion)
}@function
def example(llvmversion: str, glibcversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.glibcsysroot(llvmversion, glibcversion, linuxversion)
)@func()
example(llvmVersion: string, glibcVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.glibcSysroot(llvmVersion, glibcVersion, linuxVersion)
}gnatLlvm() 🔗
GnatLLVM builds the GNAT LLVM Ada compiler against LLVM. This is required for Ada/SPARK integration in the kernel (Issue #40).
The function: 1. Builds LLVM from source with full SDK (not toolchain-only) 2. Installs Alire and seed GNAT compiler 3. Clones GNAT LLVM and GCC Ada frontend sources 4. Builds GNAT LLVM using the LLVM SDK 5. Returns the GNAT LLVM installation directory
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
gnat-llvm --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Gnatllvm(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.gnatllvm(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.gnatLlvm(llvmVersion)
}isobuild() 🔗
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| kernelDir | Directory | - | Pre-built kernel directory from KernelBuild() If not provided, KernelBuild will be called automatically |
| toolchain | Directory | - | Pre-built Stage1 toolchain directory (passed to KernelBuild if needed) |
| llvmVersion | String ! | "21.1.8" | LLVM version to use (passed to KernelBuild if needed) |
| muslVersion | String ! | "1.2.5" | musl version for sysroot (passed to KernelBuild if needed) |
| linuxVersion | String ! | "6.12.8" | Linux kernel headers version (passed to KernelBuild if needed) |
| source | Directory | - | Repository source directory containing kernel/ and boot/limine.conf |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
isobuild --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.File {
return dag.
Terranoxbootstrap().
Isobuild(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.File:
return (
dag.terranox_bootstrap()
.isobuild(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): File {
return dag
.terranoxBootstrap()
.isobuild(llvmVersion, muslVersion, linuxVersion)
}integrationTests() 🔗
IntegrationTests runs the complete integration test suite for a release.
Tests include: - Boot test (kernel boots successfully) - Strata activation test - Toolchain smoke tests
Usage:
dagger call integration-tests --toolchain=<dir> --source=.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory ! | - | Toolchain directory to test |
| source | Directory ! | - | Repository source for test files |
| llvmVersion | String ! | "21.1.8" | No description provided |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
integration-tests --toolchain DIR_PATH --source DIR_PATH --llvm-version stringfunc (m *MyModule) Example(ctx context.Context, toolchain *dagger.Directory, source *dagger.Directory, llvmVersion string) string {
return dag.
Terranoxbootstrap().
Integrationtests(ctx, toolchain, source, llvmVersion)
}@function
async def example(toolchain: dagger.Directory, source: dagger.Directory, llvmversion: str) -> str:
return await (
dag.terranox_bootstrap()
.integrationtests(toolchain, source, llvmversion)
)@func()
async example(toolchain: Directory, source: Directory, llvmVersion: string): Promise<string> {
return dag
.terranoxBootstrap()
.integrationTests(toolchain, source, llvmVersion)
}kernelBuild() 🔗
KernelBuild compiles the TerranoxOS kernel using the Stage1 LLVM/Clang toolchain.
This function builds the kernel from C and assembly sources, producing a bootable ELF binary suitable for loading with Limine bootloader.
Example usage:
# Build kernel with existing toolchain:
dagger call kernel-build --toolchain ./toolchain/llvm export --path=./kernel.elf
# Build kernel from scratch (builds Stage1 first):
dagger call kernel-build export --path=./kernel.elf
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built Stage1 toolchain directory If not provided, Stage1 will be built automatically |
| llvmVersion | String ! | "21.1.8" | LLVM version to use |
| muslVersion | String ! | "1.2.5" | musl version for sysroot |
| linuxVersion | String ! | "6.12.8" | Linux kernel headers version |
| source | Directory | - | Repository source directory containing kernel/ and patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
kernel-build --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Kernelbuild(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.kernelbuild(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.kernelBuild(llvmVersion, muslVersion, linuxVersion)
}linuxKernelBuild() 🔗
LinuxKernelBuild compiles the mainline Linux kernel using LLVM/Clang toolchain.
This function builds a production Linux kernel with LLVM=1 for the bootable TerranoxOS system. This is separate from the custom TerranoxOS kernel - this is the real Linux kernel.
Example usage:
# Build Linux kernel with existing toolchain:
dagger call linux-kernel-build --toolchain ./toolchain/llvm export --path=./linux-build
# Build from scratch (builds Stage1 first):
dagger call linux-kernel-build export --path=./linux-build
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built Stage1 toolchain directory If not provided, Stage1 will be built automatically |
| llvmVersion | String ! | "21.1.8" | LLVM version to use |
| muslVersion | String ! | "1.2.5" | musl version for sysroot |
| linuxVersion | String ! | "6.12.8" | Linux kernel version to build |
| source | Directory | - | Repository source directory (not used, but kept for consistency) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
linux-kernel-build --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Linuxkernelbuild(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.linuxkernelbuild(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.linuxKernelBuild(llvmVersion, muslVersion, linuxVersion)
}linuxKernelImage() 🔗
LinuxKernelImage extracts just the bzImage from a Linux kernel build.
This is a convenience wrapper around LinuxKernelBuild() that returns only the compressed bootable kernel image, making it easier to use the kernel for booting or distribution.
Example usage:
# Extract kernel bzImage:
dagger call linux-kernel-image --toolchain ./toolchain/llvm export --path=./vmlinuz-terranox
# Boot directly in QEMU:
qemu-system-x86_64 -kernel vmlinuz-terranox -append "console=ttyS0" -nographic -m 256M
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built Stage1 toolchain directory |
| llvmVersion | String ! | "21.1.8" | LLVM version to use |
| muslVersion | String ! | "1.2.5" | musl version for sysroot |
| linuxVersion | String ! | "6.12.8" | Linux kernel version to build |
| source | Directory | - | Repository source directory |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
linux-kernel-image --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.File {
return dag.
Terranoxbootstrap().
Linuxkernelimage(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.File:
return (
dag.terranox_bootstrap()
.linuxkernelimage(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): File {
return dag
.terranoxBootstrap()
.linuxKernelImage(llvmVersion, muslVersion, linuxVersion)
}matrix() 🔗
Matrix runs validation tests against all LLVM versions and returns a report.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
matrixfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Matrix(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.matrix()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.matrix()
}melangeBuild() 🔗
MelangeBuild builds a package using melange and signs it with terranox key.
This function builds TerranoxOS packages (.apk) from melange YAML manifests located in derivations/melange/. All packages are signed with the terranox signing key (packages/melange.rsa) for supply chain security.
Usage:
# Build bash package:
dagger call melange-build --package=bash export --path=./packages/x86_64
# Build multiple packages:
dagger call melange-build --package=bash export --path=./build/bash
dagger call melange-build --package=ncurses export --path=./build/ncurses
Output: Signed .apk files in packages/x86_64/
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing derivations/melange/ and packages/ |
| packageName | String ! | - | Package name (must match YAML file in derivations/melange/) |
| localRepo | Directory | - | Local APK repository with previously-built packages. When provided, these packages are available as build dependencies inside the melange sandbox, enabling self-hosting bootstraps where earlier packages (e.g., musl 1.2.5) are used by later builds (e.g., git). |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
melange-build --source DIR_PATH --package-name stringfunc (m *MyModule) Example(source *dagger.Directory, packageName string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Melangebuild(source, packageName)
}@function
def example(source: dagger.Directory, packagename: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.melangebuild(source, packagename)
)@func()
example(source: Directory, packageName: string): Directory {
return dag
.terranoxBootstrap()
.melangeBuild(source, packageName)
}melangeKeygen() 🔗
MelangeKeygen generates a fresh RSA-4096 signing keypair for melange package signing. The private key is written to packages/melange.rsa and the public key to packages/melange.rsa.pub.
Only needed once — the generated keys should be committed to the repo (the private key is .gitignored in real deployments, but for local-only builds it lives alongside the repo).
Usage:
dagger call melange-keygen export --path=./packages
Return Type
Directory ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
melange-keygenfunc (m *MyModule) Example() *dagger.Directory {
return dag.
Terranoxbootstrap().
Melangekeygen()
}@function
def example() -> dagger.Directory:
return (
dag.terranox_bootstrap()
.melangekeygen()
)@func()
example(): Directory {
return dag
.terranoxBootstrap()
.melangeKeygen()
}multiSign() 🔗
MultiSign performs multi-signature signing with N of M keys for hardened releases.
Usage:
dagger call multi-sign --artifact-path=./profile.json --keys-dir=./maintainer-keys
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| artifact | File ! | - | Artifact file to sign |
| keysDir | Directory ! | - | Directory containing multiple key files (*.key) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
multi-sign --artifact file:path --keys-dir DIR_PATHfunc (m *MyModule) Example(artifact *dagger.File, keysDir *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Multisign(artifact, keysDir)
}@function
def example(artifact: dagger.File, keysdir: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.multisign(artifact, keysdir)
)@func()
example(artifact: File, keysDir: Directory): Directory {
return dag
.terranoxBootstrap()
.multiSign(artifact, keysDir)
}muslBootstrap() 🔗
MuslBootstrap builds the complete musl-based toolchain and packages it into a single output directory with a manifest.
Pre-built Stage0 and Sysroot can be passed in to skip rebuilding. This enables incremental CI where earlier stages are cached as artifacts between jobs.
Pipeline:
Alpine seed ──→ Stage0 (cross-compiler)
Alpine seed ──→ Sysroot (musl + LLVM runtimes)
Stage0 + Sysroot ──→ Stage1 (self-hosted musl Clang)
Output structure:
tools/ - Stage1 Clang, LLD, llvm-ar, etc.
sysroot/ - musl headers/libs, LLVM runtimes, kernel headers
manifest.json - Build metadata
Usage:
dagger call musl-bootstrap
dagger call musl-bootstrap --stage0=./cached-stage0 --sysroot=./cached-sysroot
dagger call musl-bootstrap export --path=./toolchain
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| stage0 | Directory | - | Pre-built Stage0 cross-tools directory. Skips Stage0 build if provided. |
| sysroot | Directory | - | Pre-built sysroot directory. Skips sysroot build if provided. |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
musl-bootstrap --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Muslbootstrap(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.muslbootstrap(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.muslBootstrap(llvmVersion)
}muslSdkSysroot() 🔗
MuslSdkSysroot extends the base musl sysroot with development library headers and static libraries from Alpine. This enables cross-compilation of userspace programs that depend on common C libraries (zlib, openssl, etc.).
The package list is driven by the [sdk] section in bootstrap.toml. Alpine packages are used because they are musl-linked and ABI-compatible with the base sysroot.
Usage:
dagger call musl-sdk-sysroot
dagger call musl-sdk-sysroot --llvm-version=21.1.8 --source=.
dagger call musl-sdk-sysroot export --path=./sdk-sysroot
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | LLVM version for runtimes |
| muslVersion | String ! | "1.2.5" | musl version |
| linuxVersion | String ! | "6.12.8" | Linux kernel version for headers |
| sysroot | Directory | - | Pre-built base sysroot directory. If not provided, the base sysroot is built from scratch via MuslSysroot. |
| source | Directory | - | Repository source directory containing patches/ and bootstrap.toml |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
musl-sdk-sysroot --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Muslsdksysroot(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.muslsdksysroot(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.muslSdkSysroot(llvmVersion, muslVersion, linuxVersion)
}muslStage0() 🔗
MuslStage0 builds the Stage 0 cross-compiler: a Clang targeting x86_64-linux-musl. Built in Alpine (musl) so all tools are musl-linked.
Host: Alpine (musl) Seed: Alpine’s Clang Output: /opt/terranox/cross-tools (Clang + LLD targeting musl)
Usage:
dagger call musl-stage0
dagger call musl-stage0 --llvm-version=21.1.8
dagger call musl-stage0 export --path=./stage0
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
musl-stage-0 --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Muslstage0(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.muslstage0(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.muslStage0(llvmVersion)
}muslStage1() 🔗
MuslStage1 builds the self-hosted Clang linked against musl. This is the final compiler with zero GNU dependencies.
Host: Alpine (musl) Compiler: Stage0 cross-compiler (built or pre-built) Links against: Sysroot (musl + LLVM runtimes, built or pre-built) Output: /opt/terranox/tools (self-hosted Clang Pre-built Stage0 and Sysroot can be passed in to skip rebuilding:
dagger call musl-stage1 --stage0=./cached-stage0 --sysroot=./cached-sysroot
dagger call musl-stage1 export --path=./stage1
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| stage0 | Directory | - | Pre-built Stage0 cross-tools directory. If not provided, Stage0 is built from scratch. |
| sysroot | Directory | - | Pre-built sysroot directory. If not provided, the sysroot is built from scratch. |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
musl-stage-1 --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Muslstage1(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.muslstage1(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.muslStage1(llvmVersion, muslVersion, linuxVersion)
}muslSysroot() 🔗
MuslSysroot builds the musl sysroot containing: - Linux kernel headers - musl libc (headers + full build) - LLVM runtimes (compiler-rt, libunwind, libc++abi, libc Host: Alpine (musl) — consistent with Stage0 and Stage1. Alpine’s native Clang builds musl directly (no cross-compilation needed) since both the host and target are musl.
Usage:
dagger call musl-sysroot
dagger call musl-sysroot export --path=./sysroot
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | LLVM version for runtimes |
| muslVersion | String ! | "1.2.5" | musl version |
| linuxVersion | String ! | "6.12.8" | Linux kernel version for headers |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
musl-sysroot --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Muslsysroot(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.muslsysroot(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Directory {
return dag
.terranoxBootstrap()
.muslSysroot(llvmVersion, muslVersion, linuxVersion)
}packageToolchainApk() 🔗
PackageToolchainApk takes the Stage1 LLVM/Clang toolchain directory and packages it as an APK that can be installed in melange build environments. This is how we close the final loop: packages are compiled with our own compiler, not Alpine’s GCC.
The APK installs to /usr (bin/clang, bin/lld, lib/clang/*, etc.) so it’s a drop-in replacement for Alpine’s clang package.
Usage:
dagger call package-toolchain-apk --source=. export --path=./out/toolchain-apk
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| toolchain | Directory | - | Pre-built Stage1 toolchain directory. If not provided, built from scratch. |
| sysroot | Directory | - | Pre-built sysroot directory. Needed for compiler-rt/libc+ |
| source | Directory | - | Repository source directory |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
package-toolchain-apk --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Packagetoolchainapk(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.packagetoolchainapk(llvmversion)
)@func()
example(llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.packageToolchainApk(llvmVersion)
}preflightToolchain() 🔗
PreflightToolchain validates all prerequisites for the toolchain melange build without actually building LLVM. Catches issues in ~2 minutes that would otherwise fail 30-60 minutes into a full build.
Checks: 1. Signing keys exist (melange.rsa 2. Melange YAML parses and environment packages install 3. Seed compiler version is sufficient (>= Clang 19) 4. LLVM source fetches and patches apply cleanly 5. musl configures with the correct CC/linker flags 6. LLVM runtimes cmake configure succeeds (without building) 7. A trivial C++ program compiles with the seed compiler Usage:
dagger call preflight-toolchain --source=.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
| llvmVersion | String ! | "21.1.8" | LLVM version to validate against |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
preflight-toolchain --source DIR_PATH --llvm-version stringfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, llvmVersion string) string {
return dag.
Terranoxbootstrap().
Preflighttoolchain(ctx, source, llvmVersion)
}@function
async def example(source: dagger.Directory, llvmversion: str) -> str:
return await (
dag.terranox_bootstrap()
.preflighttoolchain(source, llvmversion)
)@func()
async example(source: Directory, llvmVersion: string): Promise<string> {
return dag
.terranoxBootstrap()
.preflightToolchain(source, llvmVersion)
}promoteRelease() 🔗
PromoteRelease promotes a staged release to production.
This verifies signatures and moves artifacts from staging to the release registry.
Usage:
dagger call promote-release --staging=./staging --version=0.2.0
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| staging | Directory ! | - | Staging directory with signed artifacts |
| version | String ! | - | Release version |
| publicKeys | Directory ! | - | Public keys directory for signature verification |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
promote-release --staging DIR_PATH --version string --public-keys DIR_PATHfunc (m *MyModule) Example(ctx context.Context, staging *dagger.Directory, version string, publicKeys *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Promoterelease(ctx, staging, version, publicKeys)
}@function
async def example(staging: dagger.Directory, version: str, publickeys: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.promoterelease(staging, version, publickeys)
)@func()
async example(staging: Directory, version: string, publicKeys: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.promoteRelease(staging, version, publicKeys)
}qemubootTest() 🔗
QEMUBootTest boots the TerranoxOS ISO in QEMU and verifies successful boot.
This function: 1. Builds or uses pre-built ISO 2. Runs QEMU in headless mode with serial output 3. Captures serial console output 4. Verifies expected boot messages appear 5. Detects boot failures or hangs with timeout
Returns the serial console output as a string for verification.
Example usage:
# Run boot test with automatic ISO build:
dagger call qemu-boot-test
# Using pre-built ISO:
dagger call qemu-boot-test --iso ./terranox.iso
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| iso | File | - | Pre-built ISO file If not provided, ISOBuild will be called automatically |
| kernelDir | Directory | - | Pre-built kernel directory (passed to ISOBuild if needed) |
| toolchain | Directory | - | Pre-built Stage1 toolchain directory (passed to ISOBuild if needed) |
| llvmVersion | String ! | "21.1.8" | LLVM version to use (passed to ISOBuild if needed) |
| muslVersion | String ! | "1.2.5" | musl version for sysroot (passed to ISOBuild if needed) |
| linuxVersion | String ! | "6.12.8" | Linux kernel headers version (passed to ISOBuild if needed) |
| source | Directory | - | Repository source directory (passed to ISOBuild if needed) |
| timeout | Integer ! | 30 | Boot timeout in seconds |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
qemuboot-test --llvm-version string --musl-version string --linux-version string --timeout integerfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, muslVersion string, linuxVersion string, timeout int) string {
return dag.
Terranoxbootstrap().
Qemuboottest(ctxllvmVersion, muslVersion, linuxVersion, timeout)
}@function
async def example(llvmversion: str, muslversion: str, linuxversion: str, timeout: int) -> str:
return await (
dag.terranox_bootstrap()
.qemuboottest(llvmversion, muslversion, linuxversion, timeout)
)@func()
async example(llvmVersion: string, muslVersion: string, linuxVersion: string, timeout: number): Promise<string> {
return dag
.terranoxBootstrap()
.qemubootTest(llvmVersion, muslVersion, linuxVersion, timeout)
}releaseWorkflow() 🔗
ReleaseWorkflow orchestrates the complete release pipeline.
Steps: 1. Build toolchain 2. Verify reproducibility (Stage2Verify) 3. Run integration tests 4. Sign with builder key 5. Create staging registry 6. Generate release notes
Usage:
dagger call release-workflow --version=21.1.8 --source=. --builder-key=./builder.key
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | LLVM version to release |
| source | Directory ! | - | Repository source |
| builderKey | File | - | Builder key for signing |
| previousVersion | String ! | "21.0.0" | Previous version for release notes |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
release-workflow --llvm-version string --source DIR_PATH --previous-version stringfunc (m *MyModule) Example(llvmVersion string, source *dagger.Directory, previousVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Releaseworkflow(llvmVersion, source, previousVersion)
}@function
def example(llvmversion: str, source: dagger.Directory, previousversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.releaseworkflow(llvmversion, source, previousversion)
)@func()
example(llvmVersion: string, source: Directory, previousVersion: string): Directory {
return dag
.terranoxBootstrap()
.releaseWorkflow(llvmVersion, source, previousVersion)
}reproducibilityTest() 🔗
ReproducibilityTest tests if a package builds reproducibly.
This function builds a package twice in normalized environments and compares the outputs using BLAKE3 hashes. If the hashes match, the package is reproducible. If they differ, a detailed diff is generated using diffoscope.
Usage:
# Test bash package reproducibility:
dagger call reproducibility-test --source=. --package-name=bash
Output: “✓ bash is REPRODUCIBLE (hash: abc123…)” or detailed diff if not
For v0.1.0, test these 5 essential packages: - bash - musl - ncurses - coreutils - vim
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Source directory containing derivations/melange/ |
| packageName | String ! | - | Package name to test (must match YAML file in derivations/melange/) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
reproducibility-test --source DIR_PATH --package-name stringfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory, packageName string) string {
return dag.
Terranoxbootstrap().
Reproducibilitytest(ctx, source, packageName)
}@function
async def example(source: dagger.Directory, packagename: str) -> str:
return await (
dag.terranox_bootstrap()
.reproducibilitytest(source, packagename)
)@func()
async example(source: Directory, packageName: string): Promise<string> {
return dag
.terranoxBootstrap()
.reproducibilityTest(source, packageName)
}sdkImage() 🔗
SdkImage creates a Wolfi-style OCI container image with the Stage1 toolchain and the SDK sysroot installed. This is a self-contained development environment for cross-compiling userspace programs against musl with common libraries (zlib, openssl, etc.) available.
The image is modeled after Wolfi/Chainguard SDK images: - Minimal Alpine base (musl-native, no glibc compat) - Toolchain at /opt/terranox/toolchain - SDK sysroot at /opt/terranox/sysroot (includes dev headers + static libs) - Build tools (cmake, ninja, git, make, pkg-config) - PATH and sysroot env vars pre-configured
Usage:
# Export as OCI tarball:
dagger call sdk-image --source=. export --path=./terranox-sdk.tar
# Publish to registry:
dagger call sdk-image --source=. publish --address=ghcr.io/terranox-os/sdk:latest
# Interactive shell:
dagger call sdk-image --source=. terminal
Return Type
Container !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| toolchain | Directory | - | Pre-built Stage1 toolchain directory. If not provided, built from scratch. |
| sdkSysroot | Directory | - | Pre-built SDK sysroot directory. If not provided, built from scratch. |
| source | Directory | - | Repository source directory containing patches/ and bootstrap.toml |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
sdk-image --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Container {
return dag.
Terranoxbootstrap().
Sdkimage(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Container:
return (
dag.terranox_bootstrap()
.sdkimage(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Container {
return dag
.terranoxBootstrap()
.sdkImage(llvmVersion, muslVersion, linuxVersion)
}selfHostBuild() 🔗
SelfHostBuild builds all packages in dependency order, feeding earlier outputs as repositories to later builds. This is how we close the bootstrap loop: musl 1.2.5 (built in wave 1) becomes the build-host libc for git (wave 3), which needs REG_STARTEND.
Waves:
Wave 1: musl, zlib (no deps on our packages)
Wave 2: openssl, busybox, ca-certificates (may use our musl/zlib)
Wave 3: apk-tools, bash, make, ninja, git (use our openssl/zlib/musl)
Wave 4: cmake, python3 (use everything above)
Each wave’s outputs are merged into a cumulative repo that subsequent waves can pull from. Alpine repos remain available as a fallback for packages we don’t build ourselves.
Usage:
dagger call self-host-build --source=. export --path=./out/self-host
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory containing derivations/ and packages/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
self-host-build --source DIR_PATHfunc (m *MyModule) Example(source *dagger.Directory) *dagger.Directory {
return dag.
Terranoxbootstrap().
Selfhostbuild(source)
}@function
def example(source: dagger.Directory) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.selfhostbuild(source)
)@func()
example(source: Directory): Directory {
return dag
.terranoxBootstrap()
.selfHostBuild(source)
}selfHostBuildClang() 🔗
SelfHostBuildClang rebuilds all packages using the TerranoxOS Stage1 LLVM/Clang toolchain instead of Alpine’s GCC. This is the final self-hosting milestone: every package is compiled with our own compiler.
Flow: 1. Build (or accept) Stage1 toolchain 2. Package the toolchain as an APK (terranox-clang) 3. Run SelfHostBuild waves with the toolchain APK in the local repo 4. Melange manifests install terranox-clang and use CC=clang CXX=clang Usage:
dagger call self-host-build-clang --source=. export --path=./out/clang-self-host
dagger call self-host-build-clang --source=. --toolchain=./stage1 export --path=./out/clang-self-host
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
| llvmVersion | String ! | "21.1.8" | No description provided |
| toolchain | Directory | - | Pre-built Stage1 toolchain. If not provided, built from scratch. |
| sysroot | Directory | - | Pre-built sysroot. If not provided, built from scratch. |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
self-host-build-clang --source DIR_PATH --llvm-version stringfunc (m *MyModule) Example(source *dagger.Directory, llvmVersion string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Selfhostbuildclang(source, llvmVersion)
}@function
def example(source: dagger.Directory, llvmversion: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.selfhostbuildclang(source, llvmversion)
)@func()
example(source: Directory, llvmVersion: string): Directory {
return dag
.terranoxBootstrap()
.selfHostBuildClang(source, llvmVersion)
}sign() 🔗
Sign signs an artifact using Cosign with the specified key.
Usage:
dagger call sign --artifact-path=./toolchain.tar.gz --key-file=./builder.key
Return Type
File !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| artifact | File ! | - | Artifact file to sign |
| keyFile | File ! | - | Cosign private key file |
| password | String | "" | Key password (optional, use “” for passwordless keys) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
sign --artifact file:path --key-file file:pathfunc (m *MyModule) Example(artifact *dagger.File, keyFile *dagger.File) *dagger.File {
return dag.
Terranoxbootstrap().
Sign(artifact, keyFile)
}@function
def example(artifact: dagger.File, keyfile: dagger.File) -> dagger.File:
return (
dag.terranox_bootstrap()
.sign(artifact, keyfile)
)@func()
example(artifact: File, keyFile: File): File {
return dag
.terranoxBootstrap()
.sign(artifact, keyFile)
}signToolchain() 🔗
SignToolchain signs the toolchain tarball using Cosign for supply chain security.
This function: 1. Packages the toolchain directory into a tarball 2. Signs the tarball using Cosign keyless signing (OIDC) 3. Returns a directory with: toolchain.tar.gz, toolchain.tar.gz.sig, toolchain.tar.gz.bundle
For v0.1.0, we use Cosign’s experimental keyless mode for simplicity. Future versions will support: custom key files, KMS, hardware tokens.
Example usage:
# Sign toolchain with keyless mode (uses GitHub OIDC):
dagger call sign-toolchain --toolchain $(dagger call stage-1)
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built toolchain directory (output of Stage1) If not provided, will build Stage1 automatically |
| llvmVersion | String ! | "21.1.8" | LLVM version to use |
| libcVersion | String ! | "1.2.5" | C library version |
| linuxVersion | String ! | "6.12.8" | Linux kernel headers version |
| source | Directory | - | Repository source directory containing patches/ |
| variant | String ! | "musl" | Toolchain variant: “musl” or “glibc” |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
sign-toolchain --llvm-version string --libc-version string --linux-version string --variant stringfunc (m *MyModule) Example(llvmVersion string, libcVersion string, linuxVersion string, variant string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Signtoolchain(llvmVersion, libcVersion, linuxVersion, variant)
}@function
def example(llvmversion: str, libcversion: str, linuxversion: str, variant: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.signtoolchain(llvmversion, libcversion, linuxversion, variant)
)@func()
example(llvmVersion: string, libcVersion: string, linuxVersion: string, variant: string): Directory {
return dag
.terranoxBootstrap()
.signToolchain(llvmVersion, libcVersion, linuxVersion, variant)
}stage2Verify() 🔗
Stage2Verify implements reproducibility verification by building Stage1 twice and comparing the outputs using BLAKE3 hashing.
This ensures the toolchain builds are bit-for-bit identical, a critical requirement for supply chain security.
Usage:
dagger call stage2-verify --llvm-version=21.1.8 --source=.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
stage-2-verify --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, muslVersion string, linuxVersion string) string {
return dag.
Terranoxbootstrap().
Stage2verify(ctx, llvmVersion, muslVersion, linuxVersion)
}@function
async def example(llvmversion: str, muslversion: str, linuxversion: str) -> str:
return await (
dag.terranox_bootstrap()
.stage2verify(llvmversion, muslversion, linuxversion)
)@func()
async example(llvmVersion: string, muslVersion: string, linuxVersion: string): Promise<string> {
return dag
.terranoxBootstrap()
.stage2Verify(llvmVersion, muslVersion, linuxVersion)
}stagingRegistry() 🔗
StagingRegistry creates the staging registry structure for a release.
Usage:
dagger call staging-registry --toolchain=<toolchain-dir> --version=21.1.8
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory ! | - | Toolchain directory from Bootstrap() |
| version | String ! | - | Version string for the release |
| sbom | File | - | SBOM file (CycloneDX JSON) |
| provenance | File | - | Provenance file (SLSA) |
| signature | File | - | Signature file |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
staging-registry --toolchain DIR_PATH --version stringfunc (m *MyModule) Example(toolchain *dagger.Directory, version string) *dagger.Directory {
return dag.
Terranoxbootstrap().
Stagingregistry(toolchain, version)
}@function
def example(toolchain: dagger.Directory, version: str) -> dagger.Directory:
return (
dag.terranox_bootstrap()
.stagingregistry(toolchain, version)
)@func()
example(toolchain: Directory, version: string): Directory {
return dag
.terranoxBootstrap()
.stagingRegistry(toolchain, version)
}testApkoBuild() 🔗
TestApkoBuild verifies the apko pipeline by building the SDK image and checking that key packages are installed and functional.
Usage:
dagger call test-apko-build --source=.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-apko-build --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testapkobuild(ctx, source)
}@function
async def example(source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testapkobuild(source)
)@func()
async example(source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testApkoBuild(source)
}testApkoSecurity() 🔗
TestApkoSecurity builds the SDK image with full security attestation and verifies that all artifacts are present and valid.
Usage:
dagger call test-apko-security --source=.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-apko-security --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testapkosecurity(ctx, source)
}@function
async def example(source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testapkosecurity(source)
)@func()
async example(source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testApkoSecurity(source)
}testBasic() 🔗
TestBasic verifies the seed compiler can produce an executable.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-basicfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testbasic(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testbasic()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testBasic()
}testCompilerRt() 🔗
TestCompilerRT verifies compiler-rt builtins are functional.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-compiler-rtfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testcompilerrt(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testcompilerrt()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testCompilerRt()
}testFreestanding() 🔗
TestFreestanding verifies kernel-mode compilation works: -ffreestanding, -mcmodel=kernel, -mno-red-zone, inline asm.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-freestandingfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testfreestanding(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testfreestanding()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testFreestanding()
}testLibcxx() 🔗
TestLibcxx verifies libc+
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-libcxxfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testlibcxx(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testlibcxx()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testLibcxx()
}testLinker() 🔗
TestLinker verifies lld can produce executables.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-linkerfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testlinker(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testlinker()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testLinker()
}testMusl() 🔗
TestMusl downloads, compiles, and links against musl to verify the full cross-compile pipeline.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-muslfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testmusl(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testmusl()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testMusl()
}testPatchApplication() 🔗
TestPatchApplication tests that Terranox patches apply cleanly to LLVM.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-patch-application --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testpatchapplication(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testpatchapplication(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testPatchApplication(llvmVersion, source)
}testSdkSysroot() 🔗
TestSdkSysroot verifies the SDK sysroot contains development headers and static libraries, and that a simple program can compile and link against them.
Usage:
dagger call test-sdk-sysroot
dagger call test-sdk-sysroot --llvm-version=21.1.8 --source=.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ and bootstrap.toml |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-sdk-sysroot --llvm-version stringfunc (m *MyModule) Example(ctx context.Context, llvmVersion string) string {
return dag.
Terranoxbootstrap().
Testsdksysroot(ctx, llvmVersion)
}@function
async def example(llvmversion: str) -> str:
return await (
dag.terranox_bootstrap()
.testsdksysroot(llvmversion)
)@func()
async example(llvmVersion: string): Promise<string> {
return dag
.terranoxBootstrap()
.testSdkSysroot(llvmVersion)
}testStage0Build() 🔗
TestStage0Build verifies the Stage0 cross-compiler builds and works.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-stage-0-build --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Teststage0build(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.teststage0build(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testStage0Build(llvmVersion, source)
}testStage0Freestanding() 🔗
TestStage0Freestanding verifies Stage0 can compile kernel-mode code. This is critical for TerranoxOS kernel development.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-stage-0-freestanding --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Teststage0freestanding(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.teststage0freestanding(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testStage0Freestanding(llvmVersion, source)
}testStage0TerranoxTriple() 🔗
TestStage0TerranoxTriple verifies Stage0 recognizes x86_64-pc-terranox triple.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-stage-0-terranox-triple --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Teststage0terranoxtriple(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.teststage0terranoxtriple(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testStage0TerranoxTriple(llvmVersion, source)
}testStage0WithSysroot() 🔗
TestStage0WithSysroot verifies Stage0 can compile programs using the sysroot. This is the critical integration test proving the complete toolchain works.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-stage-0-with-sysroot --llvm-version string --musl-version string --linux-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, muslVersion string, linuxVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Teststage0withsysroot(ctx, llvmVersion, muslVersion, linuxVersion, source)
}@function
async def example(llvmversion: str, muslversion: str, linuxversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.teststage0withsysroot(llvmversion, muslversion, linuxversion, source)
)@func()
async example(llvmVersion: string, muslVersion: string, linuxVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testStage0WithSysroot(llvmVersion, muslVersion, linuxVersion, source)
}testStage1Build() 🔗
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-stage-1-build --llvm-version string --musl-version string --linux-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, muslVersion string, linuxVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Teststage1build(ctx, llvmVersion, muslVersion, linuxVersion, source)
}@function
async def example(llvmversion: str, muslversion: str, linuxversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.teststage1build(llvmversion, muslversion, linuxversion, source)
)@func()
async example(llvmVersion: string, muslVersion: string, linuxVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testStage1Build(llvmVersion, muslVersion, linuxVersion, source)
}testSysrootContents() 🔗
TestSysrootContents verifies the sysroot has all required files.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-sysroot-contents --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testsysrootcontents(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testsysrootcontents(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testSysrootContents(llvmVersion, source)
}testSysrootHelloWorld() 🔗
TestSysrootHelloWorld compiles and runs a static hello world using the sysroot.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-sysroot-hello-world --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testsysroothelloworld(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testsysroothelloworld(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testSysrootHelloWorld(llvmVersion, source)
}testTarget() 🔗
TestTarget verifies the compiler can target x86_64-linux-musl and x86_64-elf (freestanding).
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-targetfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testtarget(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testtarget()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testTarget()
}testTerranoxConditionals() 🔗
TestTerranoxConditionals verifies terranox macro works in real code. This tests OS-specific conditional compilation.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | No description provided |
| source | Directory ! | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-terranox-conditionals --llvm-version string --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, llvmVersion string, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testterranoxconditionals(ctx, llvmVersion, source)
}@function
async def example(llvmversion: str, source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testterranoxconditionals(llvmversion, source)
)@func()
async example(llvmVersion: string, source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testTerranoxConditionals(llvmVersion, source)
}testToolchainImage() 🔗
TestToolchainImage runs a comprehensive smoke test on the toolchain container image. Tests C compilation, C++ compilation, LLVM tools, build tools, and verifies the sysroot + clang config are wired correctly.
Usage:
# Test after building:
dagger call test-toolchain-image --source=.
# Test a pre-built image tarball:
dagger call test-toolchain-image --source=. --image-tar=./terranox-toolchain.tar
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| source | Directory ! | - | Repository source directory |
| imageTar | File | - | Pre-built OCI tarball. If not provided, builds the image from scratch. |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-toolchain-image --source DIR_PATHfunc (m *MyModule) Example(ctx context.Context, source *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Testtoolchainimage(ctx, source)
}@function
async def example(source: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.testtoolchainimage(source)
)@func()
async example(source: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.testToolchainImage(source)
}testTools() 🔗
TestTools verifies all required LLVM tools are present.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
test-toolsfunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Testtools(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.testtools()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.testTools()
}toolchainApkImage() 🔗
ToolchainApkImage creates a Docker/OCI container image by installing the toolchain APK into an Alpine base. Unlike ToolchainImage (which copies raw directories), this uses the APK package manager so the toolchain is tracked as a proper system package.
The image includes build essentials (cmake, ninja, make, git) and has clang/lld/llvm-* available in /usr/bin via the APK install.
Usage:
# Build image from scratch:
dagger call toolchain-apk-image --source=. export --path=./terranox-toolchain-apk.tar
# Build with pre-built APK directory:
dagger call toolchain-apk-image --source=. --apk-repo=./out/toolchain-apk \
export --path=./terranox-toolchain-apk.tar
# Publish to registry:
dagger call toolchain-apk-image --source=. \
publish --address ghcr.io/terranox-os/toolchain:21.1.8-apk
# Interactive shell:
dagger call toolchain-apk-image --source=. terminal
Return Type
Container !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| llvmVersion | String ! | "21.1.8" | LLVM version |
| apkRepo | Directory | - | Pre-built APK repository directory (output of PackageToolchainApk). If not provided, the APK is built from scratch. |
| toolchain | Directory | - | Pre-built Stage1 toolchain directory (passed to PackageToolchainApk if apkRepo is nil) |
| sysroot | Directory | - | Pre-built sysroot directory (passed to PackageToolchainApk if apkRepo is nil) |
| source | Directory | - | Repository source directory containing packages/ signing keys |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
toolchain-apk-image --llvm-version stringfunc (m *MyModule) Example(llvmVersion string) *dagger.Container {
return dag.
Terranoxbootstrap().
Toolchainapkimage(llvmVersion)
}@function
def example(llvmversion: str) -> dagger.Container:
return (
dag.terranox_bootstrap()
.toolchainapkimage(llvmversion)
)@func()
example(llvmVersion: string): Container {
return dag
.terranoxBootstrap()
.toolchainApkImage(llvmVersion)
}toolchainImage() 🔗
ToolchainImage creates a container image with the Stage1 toolchain installed. This allows testing in the correct musl environment and sharing between systems.
Usage:
# Export as OCI tarball:
dagger call toolchain-image --toolchain ./toolchain/llvm \
export --path ./terranox-toolchain-21.1.8.tar
# Publish to registry:
dagger call toolchain-image --toolchain ./toolchain/llvm \
publish --address ghcr.io/terranox-os/toolchain:21.1.8
# Use image with Docker/Podman:
docker load < terranox-toolchain-21.1.8.tar
docker run -it terranox-toolchain:21.1.8 clang --version
Return Type
Container !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory | - | Pre-built toolchain directory (output of Stage1 export) |
| llvmVersion | String ! | "21.1.8" | No description provided |
| muslVersion | String ! | "1.2.5" | No description provided |
| linuxVersion | String ! | "6.12.8" | No description provided |
| source | Directory | - | Repository source directory containing patches/ |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
toolchain-image --llvm-version string --musl-version string --linux-version stringfunc (m *MyModule) Example(llvmVersion string, muslVersion string, linuxVersion string) *dagger.Container {
return dag.
Terranoxbootstrap().
Toolchainimage(llvmVersion, muslVersion, linuxVersion)
}@function
def example(llvmversion: str, muslversion: str, linuxversion: str) -> dagger.Container:
return (
dag.terranox_bootstrap()
.toolchainimage(llvmversion, muslversion, linuxversion)
)@func()
example(llvmVersion: string, muslVersion: string, linuxVersion: string): Container {
return dag
.terranoxBootstrap()
.toolchainImage(llvmVersion, muslVersion, linuxVersion)
}validate() 🔗
Validate runs ALL validation tests and reports results. Each test runs independently — a failure in one doesn’t prevent the others from running.
Return Type
String ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
validatefunc (m *MyModule) Example(ctx context.Context) string {
return dag.
Terranoxbootstrap().
Validate(ctx)
}@function
async def example() -> str:
return await (
dag.terranox_bootstrap()
.validate()
)@func()
async example(): Promise<string> {
return dag
.terranoxBootstrap()
.validate()
}verificationEnv() 🔗
VerificationEnv returns a container with Frama-C, Why3, and SMT solvers configured for formal verification of TerranoxOS kernel and userspace.
Toolchain components: - Frama-C: C code analysis framework with WP (Weakest Precondition) plugin - Why3: Deductive verification platform (backend for Frama-C and Creusot) - Z3: SMT solver (most powerful, arithmetic) - CVC5: SMT solver (bitvectors, theory combinations) - Alt-Ergo: SMT solver (polymorphism, SPARK compatibility)
Usage:
dagger call verification-env terminal
dagger call frama-c-prove --source=./kernel/core --file=pmm.c
Return Type
Container ! Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
verification-envfunc (m *MyModule) Example() *dagger.Container {
return dag.
Terranoxbootstrap().
Verificationenv()
}@function
def example() -> dagger.Container:
return (
dag.terranox_bootstrap()
.verificationenv()
)@func()
example(): Container {
return dag
.terranoxBootstrap()
.verificationEnv()
}verifySecurityAttestation() 🔗
VerifySecurityAttestation verifies SBOM, signatures, and provenance of a toolchain.
This function checks: 1. SBOM is valid CycloneDX JSON 2. Signature verification (if signature file present) 3. Provenance validation (if provenance file present)
Returns verification report as string.
Example usage:
# Verify toolchain security artifacts:
dagger call verify-security-attestation --artifacts ./artifacts
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| artifacts | Directory ! | - | Directory containing SBOM, signatures, and provenance files |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
verify-security-attestation --artifacts DIR_PATHfunc (m *MyModule) Example(ctx context.Context, artifacts *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Verifysecurityattestation(ctx, artifacts)
}@function
async def example(artifacts: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.verifysecurityattestation(artifacts)
)@func()
async example(artifacts: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.verifySecurityAttestation(artifacts)
}verifyToolchain() 🔗
GenerateSBOM creates a CycloneDX 1.5 SBOM for the Stage1 toolchain. This addresses Issue #43: SBOM/Signing/Provenance for Bootstrap Toolchain.
The SBOM includes: - Toolchain metadata (LLVM version, musl version, target triple) - Component list (LLVM, Clang, lld, musl, compiler-rt, libc++, etc.) - SHA-256 hashes of all binaries - Build provenance (Dagger build ID, timestamps) - PURL identifiers for supply chain tracking
Artifact Storage Convention:
/build/artifacts/stage1-llvm-{version}/sbom.cdx.json
/build/artifacts/gnat-llvm-{version}/sbom.cdx.json
Usage:
# With pre-built toolchain (recommended):
dagger call generate-sbom --toolchain $(dagger call stage-1) --llvm-version=21.1.8 \
export --path=./build/artifacts/stage1-llvm-21.1.8/sbom.cdx.json
# Auto-build toolchain (slower):
dagger call generate-sbom --llvm-version=21.1.8 \
export --path=./build/artifacts/stage1-llvm-21.1.8/sbom.cdx.json
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| toolchain | Directory ! | - | Pre-built toolchain directory (e.g., from Stage1 export) |
Example
dagger -m github.com/terranox-os/toolchain@9bcb446e366ee56cce3acda868e0d742bdf948db call \
verify-toolchain --toolchain DIR_PATHfunc (m *MyModule) Example(ctx context.Context, toolchain *dagger.Directory) string {
return dag.
Terranoxbootstrap().
Verifytoolchain(ctx, toolchain)
}@function
async def example(toolchain: dagger.Directory) -> str:
return await (
dag.terranox_bootstrap()
.verifytoolchain(toolchain)
)@func()
async example(toolchain: Directory): Promise<string> {
return dag
.terranoxBootstrap()
.verifyToolchain(toolchain)
}