102 lines
3.0 KiB
Rust
102 lines
3.0 KiB
Rust
use std::env;
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
|
|
fn main() {
|
|
println!("cargo:rerun-if-changed=client");
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
let client_bin = build_client(&out_dir);
|
|
|
|
setup_nyx(&out_dir);
|
|
|
|
create_nyx_workdir(&out_dir, &client_bin);
|
|
}
|
|
|
|
#[track_caller]
|
|
fn shell(cwd: impl AsRef<Path>, command_string: &str) {
|
|
println!(
|
|
"cargo:warning=Running ({}) {command_string}",
|
|
cwd.as_ref().display()
|
|
);
|
|
|
|
let cwd = cwd.as_ref();
|
|
let mut parts = command_string.split(" ");
|
|
let command_name = parts.next().unwrap();
|
|
|
|
let mut command = Command::new(command_name);
|
|
command.current_dir(cwd);
|
|
command.stdout(std::process::Stdio::inherit());
|
|
command.stderr(std::process::Stdio::inherit());
|
|
command.args(parts);
|
|
|
|
let mut process = command.spawn().unwrap();
|
|
let exit_status = process.wait().unwrap();
|
|
if !exit_status.success() {
|
|
panic!(
|
|
"Command failed with {exit_status}: {}> {command_string}",
|
|
cwd.display()
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Builds the client and returns the path to its binary
|
|
fn build_client(out_dir: &str) -> String {
|
|
// Change the target dir to avoid a cargo target dir deadlock
|
|
shell(
|
|
"client",
|
|
&format!("cargo build --release --target-dir {out_dir}/client_target"),
|
|
);
|
|
format!("{out_dir}/client_target/release/client")
|
|
}
|
|
|
|
/// Downloads and compiles qemu-nyx and packer and compiles them for the current architecture
|
|
/// This means that cross-compilation is not supported
|
|
fn setup_nyx(out_dir: &str) {
|
|
let packer_path = std::path::PathBuf::from(format!("{out_dir}/packer"));
|
|
let qemu_path = std::path::PathBuf::from(format!("{out_dir}/QEMU-Nyx"));
|
|
if !packer_path.exists() {
|
|
shell(out_dir, "git clone https://github.com/nyx-fuzz/packer/");
|
|
}
|
|
if !qemu_path.exists() {
|
|
println!("cargo:warning=Cloning and building QEMU-Nyx. This may take a while...");
|
|
shell(
|
|
out_dir,
|
|
"git clone https://github.com/nyx-fuzz/QEMU-Nyx --depth 1",
|
|
);
|
|
|
|
let is_debug_build = match env::var("DEBUG").unwrap().as_str() {
|
|
"true" => true,
|
|
"false" => false,
|
|
other => panic!("Invalid value for DEBUG: {other}"),
|
|
};
|
|
let qemu_compile_mode = if is_debug_build {
|
|
"debug_static"
|
|
} else {
|
|
"lto"
|
|
};
|
|
shell(
|
|
qemu_path,
|
|
&format!("bash compile_qemu_nyx.sh {qemu_compile_mode}"),
|
|
);
|
|
}
|
|
}
|
|
|
|
fn create_nyx_workdir(out_dir: &str, client_bin: &str) {
|
|
// Create the directory and move required binaries to it
|
|
shell(
|
|
out_dir,
|
|
&format!(
|
|
"python3 packer/packer/nyx_packer.py {client_bin} build afl processor_trace --fast_reload_mode --purge"
|
|
),
|
|
);
|
|
|
|
// Create the nyx config
|
|
shell(
|
|
out_dir,
|
|
"python3 packer/packer/nyx_config_gen.py build Kernel",
|
|
);
|
|
|
|
// Pass the path to the build directory to src/main.rs
|
|
println!("cargo:rustc-env=NYX_SHAREDIR={out_dir}/build")
|
|
}
|