106 lines
3.4 KiB
Rust
106 lines
3.4 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);
|
|
}
|
|
|
|
writeln!(generated_code, "#[allow(non_camel_case_types)] pub enum Benchmark {{").unwrap();
|
|
for benchmark_name in &benchmark_functions {
|
|
writeln!(generated_code, " {benchmark_name},").unwrap();
|
|
}
|
|
writeln!(generated_code, "}}").unwrap();
|
|
|
|
writeln!(generated_code, "pub unsafe fn run(benchmark: Benchmark) {{").unwrap();
|
|
writeln!(generated_code, "match benchmark {{").unwrap();
|
|
for benchmark_name in benchmark_functions {
|
|
writeln!(generated_code, " Benchmark::{benchmark_name} => unsafe {{ {benchmark_name}() }},").unwrap();
|
|
}
|
|
writeln!(generated_code, "}}").unwrap();
|
|
writeln!(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)
|
|
}
|