David Venhoff 9ba2bbe8cd Fix compilation of embench
The separation did not work before, somehow.
The new approach of redefining the function names, while hacky, definitely works though.
2025-09-12 10:54:24 +02:00

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();
}