sdk

Radroots SDK and bindings
git clone https://radroots.dev/git/sdk.git
Log | Files | Refs | README

commit d43f72542d6296194944d95328bf172b887d3f89
parent 47656467f15b1d21b06f6b6159a8f70cb40c0d28
Author: triesap <tyson@radroots.org>
Date:   Mon,  3 Aug 2026 22:50:56 +0000

release: qualify front-door native targets

- mirror the governed toolchain and operating-system matrix
- check both front doors on MSRV and current stable
- cross-check Linux macOS and Windows library targets
- expose the locked qualification through the repository xtask

Diffstat:
Acontracts/releases/target_matrix.toml | 18++++++++++++++++++
Mtools/xtask/src/main.rs | 8+++++++-
Atools/xtask/src/target_qualification.rs | 199+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 224 insertions(+), 1 deletion(-)

diff --git a/contracts/releases/target_matrix.toml b/contracts/releases/target_matrix.toml @@ -0,0 +1,18 @@ +schema_version = 1 +msrv_toolchain = "1.97.1" +current_toolchain = "stable" + +[[operating_system]] +name = "linux" +target = "x86_64-unknown-linux-gnu" +cross_compiler = "zig cc" +cross_cflags = "-target x86_64-linux-gnu" + +[[operating_system]] +name = "macos" +target = "aarch64-apple-darwin" + +[[operating_system]] +name = "windows" +target = "x86_64-pc-windows-gnu" +cross_compiler = "x86_64-w64-mingw32-gcc" diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs @@ -15,6 +15,7 @@ mod package_matrix; mod package_metadata; mod release_qualification; mod smoke; +mod target_qualification; mod ts; mod wasm; mod wasm_declarations; @@ -31,6 +32,7 @@ enum CommandAction<'a> { GeneratePackageMetadata, Coverage(&'a [String]), QualifyFeatures, + QualifyTargets, Check, Smoke(&'a [String]), } @@ -66,6 +68,7 @@ fn run(args: impl IntoIterator<Item = String>) -> Result<(), String> { CommandAction::QualifyFeatures => { release_qualification::run_feature_matrix(&fs::workspace_root()?) } + CommandAction::QualifyTargets => target_qualification::run(&fs::workspace_root()?), CommandAction::Check => check::check(), CommandAction::Smoke(rest) => smoke::run(rest), } @@ -96,6 +99,9 @@ fn command_action(args: &[String]) -> Result<CommandAction<'_>, String> { [command, target] if command == "release" && target == "qualify-features" => { Ok(CommandAction::QualifyFeatures) } + [command, target] if command == "release" && target == "qualify-targets" => { + Ok(CommandAction::QualifyTargets) + } [command] if command == "check" => Ok(CommandAction::Check), [command, rest @ ..] if command == "smoke" => Ok(CommandAction::Smoke(rest)), [] => Err(usage()), @@ -104,7 +110,7 @@ fn command_action(args: &[String]) -> Result<CommandAction<'_>, String> { } fn usage() -> String { - "usage: cargo xtask architecture | cargo xtask architecture-ci | cargo xtask check-api-boundaries | cargo xtask check-dependency-boundaries | cargo xtask generate | cargo xtask generate ts | cargo xtask generate wasm [--package <key>] | cargo xtask generate bindings <swift|kotlin> | cargo xtask generate package-metadata | cargo xtask check | cargo xtask smoke facade-rust-local | sdk-rust-local | front-doors-rust-local | cargo xtask coverage run | cargo xtask release qualify-features" + "usage: cargo xtask architecture | cargo xtask architecture-ci | cargo xtask check-api-boundaries | cargo xtask check-dependency-boundaries | cargo xtask generate | cargo xtask generate ts | cargo xtask generate wasm [--package <key>] | cargo xtask generate bindings <swift|kotlin> | cargo xtask generate package-metadata | cargo xtask check | cargo xtask smoke facade-rust-local | sdk-rust-local | front-doors-rust-local | cargo xtask coverage run | cargo xtask release qualify-features | cargo xtask release qualify-targets" .to_owned() } diff --git a/tools/xtask/src/target_qualification.rs b/tools/xtask/src/target_qualification.rs @@ -0,0 +1,199 @@ +use std::{fs, path::Path, process::Command}; + +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +struct TargetMatrix { + schema_version: u32, + msrv_toolchain: String, + current_toolchain: String, + operating_system: Vec<OperatingSystem>, +} + +#[derive(Debug, Deserialize)] +struct OperatingSystem { + name: String, + target: String, + cross_compiler: Option<String>, + cross_cflags: Option<String>, +} + +#[derive(Debug, Deserialize)] +struct Architecture { + repositories: Repositories, +} + +#[derive(Debug, Deserialize)] +struct Repositories { + sdk: Repository, +} + +#[derive(Debug, Deserialize)] +struct Repository { + packages: Vec<String>, +} + +pub fn run(workspace_root: &Path) -> Result<(), String> { + let (matrix, packages) = load(workspace_root)?; + for toolchain in [&matrix.msrv_toolchain, &matrix.current_toolchain] { + run_command( + workspace_root, + "rustup", + &[ + "run", + toolchain, + "cargo", + "check", + "--workspace", + "--all-targets", + "--locked", + ], + )?; + } + for operating_system in matrix.operating_system { + for package in &packages { + run_target_command( + workspace_root, + &operating_system, + &[ + "check", + "-p", + package, + "--lib", + "--target", + &operating_system.target, + "--locked", + ], + )?; + } + } + Ok(()) +} + +fn load(workspace_root: &Path) -> Result<(TargetMatrix, Vec<String>), String> { + let matrix_path = workspace_root.join("contracts/releases/target_matrix.toml"); + let matrix = toml::from_str::<TargetMatrix>(&read(&matrix_path)?) + .map_err(|error| format!("failed to parse {}: {error}", matrix_path.display()))?; + validate(&matrix)?; + + let architecture_path = workspace_root.join("docs/specs/radroots_crates_release_v1.toml"); + let architecture = toml::from_str::<Architecture>(&read(&architecture_path)?) + .map_err(|error| format!("failed to parse {}: {error}", architecture_path.display()))?; + let mut packages = architecture.repositories.sdk.packages; + packages.sort(); + if packages != ["radroots", "radroots_sdk"] { + return Err(format!( + "target qualification requires exactly the two SDK front doors, found {packages:?}" + )); + } + Ok((matrix, packages)) +} + +fn read(path: &Path) -> Result<String, String> { + fs::read_to_string(path).map_err(|error| format!("failed to read {}: {error}", path.display())) +} + +fn validate(matrix: &TargetMatrix) -> Result<(), String> { + if matrix.schema_version != 1 { + return Err(format!( + "target matrix schema_version must be 1, found {}", + matrix.schema_version + )); + } + if matrix.msrv_toolchain != "1.97.1" || matrix.current_toolchain != "stable" { + return Err("target matrix must retain MSRV 1.97.1 and current stable".to_owned()); + } + let expected = [ + ( + "linux", + "x86_64-unknown-linux-gnu", + Some("zig cc"), + Some("-target x86_64-linux-gnu"), + ), + ("macos", "aarch64-apple-darwin", None, None), + ( + "windows", + "x86_64-pc-windows-gnu", + Some("x86_64-w64-mingw32-gcc"), + None, + ), + ]; + if matrix.operating_system.len() != expected.len() + || expected.iter().any(|(name, target, compiler, cflags)| { + !matrix.operating_system.iter().any(|entry| { + entry.name == *name + && entry.target == *target + && entry.cross_compiler.as_deref() == *compiler + && entry.cross_cflags.as_deref() == *cflags + }) + }) + { + return Err( + "target matrix must contain the exact Linux, macOS, and Windows triples".to_owned(), + ); + } + Ok(()) +} + +fn run_target_command( + workspace_root: &Path, + operating_system: &OperatingSystem, + args: &[&str], +) -> Result<(), String> { + eprintln!("cargo {}", args.join(" ")); + let mut command = Command::new("cargo"); + command.args(args).current_dir(workspace_root); + let target_key = operating_system.target.replace('-', "_"); + if let Some(compiler) = operating_system.cross_compiler.as_deref() { + command.env(format!("CC_{target_key}"), compiler); + } + if let Some(cflags) = operating_system.cross_cflags.as_deref() { + command.env(format!("CFLAGS_{target_key}"), cflags); + } + let status = command + .status() + .map_err(|error| format!("failed to start cargo: {error}"))?; + if status.success() { + Ok(()) + } else { + Err(format!( + "target qualification failed: cargo {}", + args.join(" ") + )) + } +} + +fn run_command(workspace_root: &Path, program: &str, args: &[&str]) -> Result<(), String> { + eprintln!("{program} {}", args.join(" ")); + let status = Command::new(program) + .args(args) + .current_dir(workspace_root) + .status() + .map_err(|error| format!("failed to start {program}: {error}"))?; + if status.success() { + Ok(()) + } else { + Err(format!( + "target qualification failed: {program} {}", + args.join(" ") + )) + } +} + +#[cfg(test)] +mod tests { + use super::load; + + #[test] + fn current_contract_selects_exact_toolchains_targets_and_packages() { + let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .parent() + .and_then(std::path::Path::parent) + .expect("workspace root"); + let (matrix, packages) = load(root).expect("target matrix"); + assert_eq!(matrix.msrv_toolchain, "1.97.1"); + assert_eq!(matrix.current_toolchain, "stable"); + assert_eq!(matrix.operating_system.len(), 3); + assert_eq!(packages, ["radroots", "radroots_sdk"]); + } +}