CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
89 lines
3.5 KiB
Rust
89 lines
3.5 KiB
Rust
//! Build script: generate the third-party dependency/license manifest
|
|
//! that `mirage about` prints.
|
|
//!
|
|
//! At build time we ask cargo for the fully-resolved dependency graph
|
|
//! (`cargo metadata`) and distil it into a small, sorted text manifest
|
|
//! of every crate mirage links, with its version and SPDX license. The
|
|
//! manifest is written to `OUT_DIR/about.txt` and embedded into the
|
|
//! binary via `include_str!`, so `mirage about` needs no files at
|
|
//! runtime and the list can never drift from what was actually built.
|
|
//!
|
|
//! The generation is best-effort: if `cargo metadata` is unavailable
|
|
//! (e.g. a restricted offline build) we still emit a valid, if sparse,
|
|
//! manifest so the build never fails on account of `about`.
|
|
|
|
use std::path::PathBuf;
|
|
|
|
fn main() {
|
|
// Only regenerate when the resolved dependency set changes.
|
|
println!("cargo:rerun-if-changed=Cargo.lock");
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
|
|
let out_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR set by cargo"));
|
|
let manifest = generate_manifest().unwrap_or_else(|e| {
|
|
println!("cargo:warning=mirage about: could not build dependency manifest: {e}");
|
|
String::from("(third-party dependency manifest unavailable for this build)\n")
|
|
});
|
|
std::fs::write(out_dir.join("about.txt"), manifest).expect("write about.txt");
|
|
}
|
|
|
|
/// Run `cargo metadata` and render the dependency/license manifest.
|
|
fn generate_manifest() -> Result<String, String> {
|
|
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
|
|
let output = std::process::Command::new(cargo)
|
|
.args(["metadata", "--format-version", "1", "--all-features"])
|
|
.output()
|
|
.map_err(|e| format!("spawn cargo metadata: {e}"))?;
|
|
if !output.status.success() {
|
|
return Err(format!("cargo metadata exited with {}", output.status));
|
|
}
|
|
|
|
let value: serde_json::Value =
|
|
serde_json::from_slice(&output.stdout).map_err(|e| format!("parse metadata json: {e}"))?;
|
|
let packages = value
|
|
.get("packages")
|
|
.and_then(|p| p.as_array())
|
|
.ok_or("metadata has no packages array")?;
|
|
|
|
// Collect (name, version, license) for every resolved crate, skipping
|
|
// the mirage workspace crates themselves (they're first-party).
|
|
let mut entries: Vec<(String, String, String)> = Vec::new();
|
|
for pkg in packages {
|
|
let name = pkg.get("name").and_then(|v| v.as_str()).unwrap_or("");
|
|
if name.is_empty()
|
|
|| name == "mirage"
|
|
|| name.starts_with("mirage_")
|
|
|| name == "rocjitsu_sys"
|
|
{
|
|
continue;
|
|
}
|
|
let version = pkg.get("version").and_then(|v| v.as_str()).unwrap_or("");
|
|
let license = pkg
|
|
.get("license")
|
|
.and_then(|v| v.as_str())
|
|
.filter(|s| !s.is_empty())
|
|
.map(str::to_string)
|
|
.or_else(|| {
|
|
pkg.get("license_file")
|
|
.and_then(|v| v.as_str())
|
|
.filter(|s| !s.is_empty())
|
|
.map(|f| format!("see {f}"))
|
|
})
|
|
.unwrap_or_else(|| "(unspecified)".to_string());
|
|
entries.push((name.to_string(), version.to_string(), license));
|
|
}
|
|
|
|
entries.sort();
|
|
entries.dedup();
|
|
|
|
let mut out = String::new();
|
|
out.push_str(&format!(
|
|
"mirage links {} third-party crate(s):\n\n",
|
|
entries.len()
|
|
));
|
|
for (name, version, license) in &entries {
|
|
out.push_str(&format!(" {name} {version} — {license}\n"));
|
|
}
|
|
Ok(out)
|
|
}
|