use std::{ffi::OsStr, process::Command, fs};
use tempfile::TempPath;
use crate::{
helper::{make_tempdir, get_criterion_env_var, make_empty_tempfile, make_spec_tempfile},
runner::{run_command, CommunicatingBenchmark}, BenchSpec,
};
const ZIG_COMPILER_INPUT_FILE: &str = "bench.zig";
const ZIG_COMPILER_OUTPUT_FILE: &str = "bench";
const HARNESS: &str = include_str!("harness.zig.in");
const SOURCE_EXTENSION: &str = ".zig";
pub fn compile(spec: BenchSpec) -> TempPath {
let zig_temp_code = make_spec_tempfile(self::SOURCE_EXTENSION, HARNESS, &spec);
let zig_temp_dir = make_tempdir();
let zig_temp_dir_code_path = zig_temp_dir.path().join(ZIG_COMPILER_INPUT_FILE);
let zig_temp_dir_exe_path = zig_temp_dir.path().join(ZIG_COMPILER_OUTPUT_FILE);
fs::copy(&zig_temp_code, &zig_temp_dir_code_path)
.expect("couldn't copy Zig code to temporary directory");
let zig_path = get_criterion_env_var("ZIG", "zig");
let mut compiler_command = Command::new(zig_path);
compiler_command
.current_dir(&zig_temp_dir)
.arg("build-exe")
.arg(&zig_temp_dir_code_path);
run_command("compiling Zig", &mut compiler_command, Some(zig_temp_code));
let temp_executable = make_empty_tempfile(super::BIN_EXTENSION);
let copy_result = fs::copy(&zig_temp_dir_exe_path, &temp_executable);
if let Err(e) = copy_result {
let zig_temp_dir = zig_temp_dir.into_path();
panic!(
"Could not copy Zig executable from expected path `{exe}`: {e}\n\n\
Temporary directory preserved: `{dir}`",
exe=zig_temp_dir_exe_path.display(),
dir=zig_temp_dir.display(),
);
}
temp_executable
}
pub fn spawn(executable: impl AsRef<OsStr>) -> CommunicatingBenchmark {
let command = Command::new(executable.as_ref());
CommunicatingBenchmark::start("running Zig", command, None)
}