The separation did not work before, somehow. The new approach of redefining the function names, while hacky, definitely works though.
101 lines
3.0 KiB
Rust
101 lines
3.0 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();
|
|
|
|
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().replace("-", "_");
|
|
println!("cargo:warning={path:?}");
|
|
|
|
let mut build = cc::Build::new();
|
|
build
|
|
.include(embench_dir.join("support"))
|
|
.file(embench_dir.join("support/beebsc.c"))
|
|
.file(&path)
|
|
// Just use some roughly accurate value, it just influences how long each benchmark runs
|
|
.define("CPU_MHZ", "2700");
|
|
|
|
// Rename all functions that are defined multiple times to avoid collisions
|
|
let colliding_functions = [
|
|
"benchmark",
|
|
"initialise_benchmark",
|
|
"warm_caches",
|
|
"verify_benchmark",
|
|
];
|
|
for name in colliding_functions {
|
|
build.define(name, format!("{benchmark_name}_{name}").as_str());
|
|
}
|
|
|
|
build.compile(&format!("libembench_{benchmark_name}.a"));
|
|
|
|
write!(
|
|
generated_code,
|
|
r#"
|
|
#[allow(non_camel_case_types)] pub struct {benchmark_name};
|
|
|
|
unsafe extern "C" {{
|
|
fn {benchmark_name}_benchmark();
|
|
fn {benchmark_name}_initialise_benchmark();
|
|
}}
|
|
|
|
impl Benchmark for {benchmark_name} {{
|
|
unsafe fn init() {{
|
|
unsafe {{ {benchmark_name}_initialise_benchmark(); }}
|
|
}}
|
|
|
|
unsafe fn benchmark() {{
|
|
unsafe {{ {benchmark_name}_benchmark(); }}
|
|
}}
|
|
}}
|
|
"#
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fs::write(format!("{out_dir}/libembench-sys.rs"), generated_code).unwrap();
|
|
}
|