use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
fn main() {
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let repo_root = manifest_dir.join("../..").canonicalize().unwrap();
build_static(
&repo_root.join("tests/rootfs-helper.c"),
&repo_root.join("tests/rootfs-helper"),
&["musl-gcc", "cc"],
&["-static", "-O2"],
"cannot compile tests/rootfs-helper: chroot tests will fail. \
Install musl-tools or static libc.",
);
let stub_src = manifest_dir.join("src/checkpoint/restore-stub.c");
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let stub_bin = out_dir.join("restore-stub");
build_static(
&stub_src,
&stub_bin,
&["cc"],
&["-static", "-nostdlib", "-no-pie", "-O2"],
"cannot compile restore-stub: its restore tests will be skipped.",
);
println!("cargo:rustc-env=RESTORE_STUB_PATH={}", stub_bin.display());
}
fn build_static(src: &Path, bin: &Path, ccs: &[&str], args: &[&str], warn: &str) {
println!("cargo:rerun-if-changed={}", src.display());
if !src.exists() {
return;
}
if bin.exists() {
if let (Ok(s), Ok(b)) = (src.metadata(), bin.metadata()) {
if let (Ok(st), Ok(bt)) = (s.modified(), b.modified()) {
if bt >= st {
return;
}
}
}
}
for cc in ccs {
let ok = Command::new(cc)
.args(args)
.arg("-o")
.arg(bin)
.arg(src)
.status()
.map(|s| s.success())
.unwrap_or(false);
if ok {
return;
}
}
println!("cargo:warning={warn}");
}