use std::env;
use std::path::PathBuf;
use std::process::Command;
const VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg(target_family = "windows")]
compile_error!("honggfuzz-rs does not currently support Windows but works well under WSL (Windows Subsystem for Linux)");
#[track_caller]
fn run_cmd(cmd: &mut Command) -> anyhow::Result<()> {
let full = Vec::from_iter(
std::iter::once(cmd.get_program())
.chain(cmd.get_args())
.map(|x| x.to_string_lossy().to_string()),
)
.join(" ");
let status = cmd
.status()
.expect(format!("Failed to spawn process \"{full}\"").as_str());
if !status.success() {
anyhow::bail!("Command failed ({:?}): \"{}\"", &status, &full);
}
Ok(())
}
fn main() -> anyhow::Result<()> {
let mut make = make_cmd::gnu_make();
let honggfuzz_target = match env::var("CARGO_HONGGFUZZ_TARGET_DIR") {
Ok(path) => PathBuf::from(path), Err(_) => return Ok(()),
};
let out_dir = PathBuf::from(env::var("OUT_DIR")?); let crate_root = PathBuf::from(env::var("CRATE_ROOT")?);
let honggfuzz_target = if honggfuzz_target.is_absolute() {
honggfuzz_target
} else {
crate_root.join(honggfuzz_target)
};
let honggfuzz_build_version =
env::var("CARGO_HONGGFUZZ_BUILD_VERSION").unwrap_or("unknown".to_string());
if VERSION != honggfuzz_build_version {
anyhow::bail!("The version of the honggfuzz library dependency ({0}) and the version of the `cargo-hfuzz` executable ({1}) do not match.\n\
If updating both by running `cargo update` and `cargo install honggfuzz` does not work, you can either:\n\
- change the dependency in `Cargo.toml` to `honggfuzz = \"={1}\"`\n\
- or run `cargo install honggfuzz --version {0}`",
VERSION, honggfuzz_build_version);
}
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?);
let manifest_dir = manifest_dir.canonicalize()?;
let manifest_dir = manifest_dir.as_path();
run_cmd(
make.args("-C honggfuzz clean".split_ascii_whitespace())
.current_dir(manifest_dir),
)?;
run_cmd(
make.args(
"-C honggfuzz honggfuzz libhfuzz/libhfuzz.a libhfcommon/libhfcommon.a"
.split_ascii_whitespace(),
)
.current_dir(manifest_dir),
)?;
use fs_err as fs;
fs::copy("honggfuzz/libhfuzz/libhfuzz.a", out_dir.join("libhfuzz.a"))?;
fs::copy(
"honggfuzz/libhfcommon/libhfcommon.a",
out_dir.join("libhfcommon.a"),
)?;
fs::copy("honggfuzz/honggfuzz", honggfuzz_target.join("honggfuzz"))?;
println!("cargo:rustc-link-lib=static={}", "hfuzz");
println!("cargo:rustc-link-lib=static={}", "hfcommon");
println!("cargo:rustc-link-search=native={}", out_dir.display());
Ok(())
}