- A recorder that holds the envelopes checks the claim against them. SessionRecorder::received_envelope takes an object's bytes and derives its content hash, counted and transferred bytes, and (at the tally) whether any of its outputs was presented; seal_checked takes the envelopes the recorder holds and runs check_session_envelopes, so an entry naming a capability its envelope does not give is refused before it leaves the sink (session_source_mismatch). stage_measure::session::recorder_of hands the title's envelopes to the recorder. - wai-web's SessionHandle: received(envelope) takes the bytes alone and the recorder derives `presented`; decoderFor refuses a via that is neither the manifest's capability nor its fallback; verifyClaim takes the envelopes; presented's layers and decoder and qualityRgb8's w and h are read as JS numbers and refused unless whole and in range (int_in), never truncated or wrapped. - build_info::profile_label decides on OPT_LEVEL alone: 2, 3, s and z are release, 0 and 1 (or an unreported level) debug; cargo's PROFILE is not read. BuildProfile's doc and jwp-receipts §2.4.8's `build` row say so. A size-optimised WebAssembly build is release. - staged-measure-conformance/README.md no longer calls every title synthetic: the wai.audio.int_codec vector codes a recorded sound. Tests: session_recorder::a_recorder_holding_its_envelopes_checks_them; the fixture session test requires the envelopes held and checked; build_info's literals; measure::a_decoder_is_named_through_its_envelopes_capability and integers_from_js_are_whole_and_in_range (wai-web native count 21 -> 23). verify_measure_wasm.mjs adds envelope verdicts (wasm32, native and Python agree), the via refusal, derived `presented`, and the JS integer cases. Co-Authored-By: Claude Opus 5.5 <[email protected]>
115 lines
4.7 KiB
Rust
115 lines
4.7 KiB
Rust
//! Cross-platform linker paths for the C libraries we wrap.
|
|
//!
|
|
//! Most of our codec deps (`opus`, `jpegxl-rs`, `dav1d`, `zstd`, `xz2`,
|
|
//! `libavif-image`) already have build.rs files that probe pkg-config
|
|
//! themselves. `flac-bound` does NOT — it just links `-lflac` and
|
|
//! expects the linker to find it. On Homebrew macOS that lives under
|
|
//! `/opt/homebrew/opt/flac/lib`, which Cargo doesn't probe. We use the
|
|
//! `pkg-config` crate to discover the right path on whatever system
|
|
//! the user is on (Linux distros, macOS Homebrew, BSD ports, etc.).
|
|
//!
|
|
//! This replaces the macOS-hardcoded `.cargo/config.toml` rustflags.
|
|
|
|
#[path = "src/build_info.rs"]
|
|
mod build_info;
|
|
|
|
fn main() {
|
|
generate_c_header();
|
|
record_build();
|
|
// Only the `codecs` feature compiles flac-bound — and pkg-config's
|
|
// probe() emits a `cargo:rustc-link-lib=flac` of its own, so running
|
|
// it unconditionally makes every consumer (e.g. the wasm32 world
|
|
// build, the wai-world-relay binary) link libFLAC it never calls.
|
|
if std::env::var_os("CARGO_FEATURE_CODECS").is_some() {
|
|
link_libflac();
|
|
}
|
|
}
|
|
|
|
/// Record the build for a measurement report (`extensions/energy-measurement.md`
|
|
/// §5, §8): the profile, from cargo's `OPT_LEVEL` (`src/build_info.rs`), the
|
|
/// target triple, and the compiler's version line.
|
|
/// A part that cannot be determined is left unset and reads as `null`.
|
|
fn record_build() {
|
|
println!("cargo:rerun-if-env-changed=OPT_LEVEL");
|
|
println!("cargo:rerun-if-env-changed=TARGET");
|
|
println!("cargo:rerun-if-env-changed=RUSTC");
|
|
let var = |k: &str| std::env::var(k).unwrap_or_default();
|
|
println!(
|
|
"cargo:rustc-env=WAI_BUILD_PROFILE={}",
|
|
build_info::profile_label(&var("OPT_LEVEL"))
|
|
);
|
|
let target = var("TARGET");
|
|
if !target.is_empty() {
|
|
println!("cargo:rustc-env=WAI_BUILD_TARGET={target}");
|
|
}
|
|
let rustc = std::env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
|
|
if let Ok(out) = std::process::Command::new(rustc).arg("-V").output() {
|
|
let line = String::from_utf8_lossy(&out.stdout).trim().to_owned();
|
|
if out.status.success() && !line.is_empty() && !line.contains('\n') {
|
|
println!("cargo:rustc-env=WAI_BUILD_TOOLCHAIN={line}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Regenerate `include/wai.h` from the FFI surface so SDK consumers can
|
|
/// always grab a typed header that matches the shipped binary. Only
|
|
/// regenerates when source files actually change (cargo handles this
|
|
/// via `rerun-if-changed` declarations).
|
|
fn generate_c_header() {
|
|
println!("cargo:rerun-if-changed=src/ffi.rs");
|
|
println!("cargo:rerun-if-changed=src/ffi_codecs.rs");
|
|
println!("cargo:rerun-if-changed=src/ffi_neural.rs");
|
|
println!("cargo:rerun-if-changed=src/container.rs");
|
|
println!("cargo:rerun-if-changed=cbindgen.toml");
|
|
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
|
let out_path = std::path::Path::new(&crate_dir).join("include/wai.h");
|
|
if let Err(e) = std::fs::create_dir_all(out_path.parent().unwrap()) {
|
|
println!("cargo:warning=cbindgen: could not create include/ dir: {e}");
|
|
return;
|
|
}
|
|
match cbindgen::Builder::new()
|
|
.with_crate(&crate_dir)
|
|
.with_config(cbindgen::Config::from_file(
|
|
std::path::Path::new(&crate_dir).join("cbindgen.toml")).unwrap_or_default())
|
|
.generate()
|
|
{
|
|
Ok(bindings) => {
|
|
bindings.write_to_file(&out_path);
|
|
}
|
|
Err(e) => {
|
|
println!("cargo:warning=cbindgen failed: {e}");
|
|
}
|
|
}
|
|
}
|
|
|
|
fn link_libflac() {
|
|
if let Ok(lib) = pkg_config::Config::new()
|
|
.atleast_version("1.3")
|
|
.probe("flac")
|
|
{
|
|
for path in &lib.link_paths {
|
|
println!("cargo:rustc-link-search=native={}", path.display());
|
|
}
|
|
// pkg-config also emits the library names; flac-bound links its
|
|
// own `-lflac` directive so we only need the search path.
|
|
} else {
|
|
// Fallback: try the canonical Homebrew location on macOS so the
|
|
// common case still works without pkg-config installed.
|
|
#[cfg(target_os = "macos")]
|
|
{
|
|
let candidates = [
|
|
"/opt/homebrew/opt/flac/lib", // arm64 macOS (Homebrew)
|
|
"/usr/local/opt/flac/lib", // x86_64 macOS (Homebrew)
|
|
];
|
|
for p in candidates {
|
|
if std::path::Path::new(p).exists() {
|
|
println!("cargo:rustc-link-search=native={p}");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
// Linux/other: hope that the system linker finds -lflac on its own.
|
|
// If not, the link error will be obvious ("cannot find -lflac")
|
|
// and the user needs to install libflac-dev / equivalent.
|
|
}
|
|
}
|