David Venhoff 2d88a8539f Move install nyx functionality from build script to runtime
It did not make a lot of sense to have that in the buildscript, as that will make nyx_runner dependent on the target directory.
This also allows specifying a binary to trace at runtime
2025-09-07 14:36:02 +02:00

98 lines
2.9 KiB
Rust

use std::fmt::Write;
use std::path::PathBuf;
use std::process::Command;
use std::str::FromStr;
use std::{env, fs};
const BENCHMARKS: &[&str] = &[
"src/ud/libud.c",
// "src/wikisort/libwikisort.c", Error: undefined reference to rand_beebs
"src/nbody/nbody.c",
"src/edn/libedn.c",
"src/st/libst.c",
"src/aha-mont64/mont64.c",
"src/matmult-int/matmult-int.c",
"src/slre/libslre.c",
"src/tarfind/tarfind.c",
"src/sglib-combined/combined.c",
"src/huffbench/libhuffbench.c",
"src/nsichneu/libnsichneu.c",
"src/minver/libminver.c",
"src/statemate/libstatemate.c",
"src/crc32/crc_32.c",
"src/picojpeg/libpicojpeg.c",
"src/cubic/basicmath_small.c",
"src/md5sum/md5.c",
"src/qrduino/qrtest.c",
"src/nettle-aes/nettle-aes.c",
"src/primecount/primecount.c",
"src/nettle-sha256/nettle-sha256.c",
];
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = env::var("OUT_DIR").unwrap();
Command::new("git")
.args(&["clone", "https://github.com/embench/embench-iot"])
.current_dir(&out_dir)
.spawn()
.unwrap()
.wait()
.unwrap();
let embench_dir = PathBuf::from_str(&format!("{out_dir}/embench-iot")).unwrap();
let mut generated_code = String::new();
let mut benchmark_functions = vec![];
for &benchmark_file in BENCHMARKS {
let path = embench_dir.join(benchmark_file);
let dir = path.parent().unwrap();
let benchmark_name = dir.file_name().unwrap().to_string_lossy();
let (wrapper_path, function_name) = make_wrapper(&benchmark_name, &out_dir);
cc::Build::new()
.include(embench_dir.join("support"))
.include(dir)
.file(&path)
.file(&wrapper_path)
.define("CPU_MHZ", "2700") // FIXME: Use correct CPU frequency
.compile(&format!("libembench_{benchmark_name}.a"));
write!(
generated_code,
r#"
unsafe extern "C" {{
fn {function_name}();
}}"#
)
.unwrap();
benchmark_functions.push(function_name);
}
write!(generated_code, "pub unsafe fn benchmark_all() {{ ").unwrap();
for function_name in benchmark_functions {
write!(generated_code, "unsafe {{ {function_name}(); }}\n").unwrap();
}
write!(generated_code, "}}").unwrap();
fs::write(&format!("{out_dir}/libembench-sys.rs"), generated_code).unwrap();
}
fn make_wrapper(benchmark_name: &str, out_dir: &str) -> (PathBuf, String) {
let benchmark_name = benchmark_name.replace("-", "_");
let function_name = format!("benchmark_{benchmark_name}");
let code = format!(
r#"
extern int benchmark(void);
void {function_name}(void) {{
benchmark();
}}
"#
);
let path = PathBuf::from(out_dir).join(&format!("{benchmark_name}_wrapper.c"));
fs::write(&path, code).unwrap();
(path, function_name)
}