use std::env;
use std::fs;
use std::path::{Path, PathBuf};
const EXTERNALIZED_PYODIDE_ASSETS: &[&str] = &[
"pyodide.asm.wasm",
"pyodide.asm.js",
"python_stdlib.zip",
"numpy-2.2.5-cp313-cp313-pyodide_2025_0_wasm32.whl",
"pandas-2.3.3-cp313-cp313-pyodide_2025_0_wasm32.whl",
];
fn main() {
let manifest_dir =
PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR must be set"));
let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR must be set"));
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-check-cfg=cfg(agentos_pyodide_unavailable)");
agentos_build_support::build_v8_bridge(&manifest_dir, &out_dir);
stage_pyodide_assets(&manifest_dir, &out_dir);
}
fn stage_pyodide_assets(manifest_dir: &Path, out_dir: &Path) {
let pyodide_out = out_dir.join("pyodide");
fs::create_dir_all(&pyodide_out).unwrap_or_else(|error| {
panic!(
"failed to create pyodide staging dir {}: {}",
pyodide_out.display(),
error
)
});
let mut pyodide_unavailable = false;
for asset in EXTERNALIZED_PYODIDE_ASSETS {
let in_tree = manifest_dir.join("assets/pyodide").join(asset);
let dest = pyodide_out.join(asset);
println!("cargo:rerun-if-changed={}", in_tree.display());
if dest.exists() && !is_placeholder(&dest) {
continue;
}
if in_tree.exists() {
fs::copy(&in_tree, &dest).unwrap_or_else(|error| {
panic!(
"failed to copy pyodide asset {} to {}: {}",
in_tree.display(),
dest.display(),
error
)
});
} else {
pyodide_unavailable = true;
fs::write(&dest, b"").unwrap_or_else(|error| {
panic!(
"failed to write pyodide placeholder {}: {}",
dest.display(),
error
)
});
}
}
if pyodide_unavailable {
println!("cargo:rustc-cfg=agentos_pyodide_unavailable");
println!(
"cargo:warning=agentos-execution: building without bundled Pyodide assets; \
guest Python execution will be unavailable in this build."
);
}
}
fn is_placeholder(path: &Path) -> bool {
fs::metadata(path)
.map(|meta| meta.len() == 0)
.unwrap_or(false)
}