use std::{ffi::OsStr, process::Command, env};
use tempfile::TempPath;
use crate::{
helper::{make_empty_tempfile, make_tempdir, get_criterion_env_var, make_spec_tempfile},
runner::{run_command, CommunicatingBenchmark}, BenchSpec,
};
const HARNESS: &str = include_str!("harness.c.in");
const SOURCE_EXTENSION: &str = ".c";
pub fn compile(
spec: BenchSpec,
mut builder: cc::Build,
) -> TempPath {
const NULL_SIGIL: &str = "\0";
let criterion_c_env_var = get_criterion_env_var("CC", NULL_SIGIL);
if criterion_c_env_var != NULL_SIGIL {
builder.compiler(criterion_c_env_var);
}
let builder_dir = make_tempdir();
builder
.out_dir(&builder_dir)
.target(env!("TARGET"))
.opt_level_str(env!("OPT_LEVEL"))
.host(env!("HOST"))
.cargo_metadata(false);
if spec.global.is_some() {
builder.define("CRITERION_BENCH_INIT", None);
}
if spec.sample.is_some() {
builder.define("CRITERION_BENCH_SETUP", None);
}
let source_file = make_spec_tempfile(self::SOURCE_EXTENSION, HARNESS, &spec);
let executable = make_empty_tempfile(super::BIN_EXTENSION);
let mut cc_command = builder.get_compiler().to_command();
cc_command
.arg("-o")
.arg(&executable)
.arg(&source_file);
run_command("compiling C", &mut cc_command, Some(source_file));
executable
}
pub fn spawn(executable: impl AsRef<OsStr>) -> CommunicatingBenchmark {
let command = Command::new(executable.as_ref());
CommunicatingBenchmark::start("running C", command, None)
}