Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 06e8fc6

Browse files
committed
Collect all function names to an array
Use a build script for `libm-test` to enumerate all symbols provided by `libm` and provide this list in a variable. This will allow us to make sure no functions are missed anytime they must be manually listed. Additionally, introduce some helper config options.
1 parent 006c2e6 commit 06e8fc6

File tree

2 files changed

+100
-3
lines changed

2 files changed

+100
-3
lines changed

crates/libm-test/build.rs

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,106 @@
1+
use std::fmt::Write;
2+
use std::path::PathBuf;
3+
use std::{env, fs};
4+
15
fn main() {
6+
let cfg = Config::from_env();
7+
8+
emit_optimization_cfg(&cfg);
9+
emit_cfg_shorthands(&cfg);
10+
list_all_tests(&cfg);
11+
212
#[cfg(feature = "test-musl-serialized")]
3-
musl_reference_tests::generate();
13+
musl_serialized_tests::generate();
14+
}
15+
16+
#[allow(dead_code)]
17+
struct Config {
18+
manifest_dir: PathBuf,
19+
out_dir: PathBuf,
20+
opt_level: u8,
21+
target_arch: String,
22+
target_env: String,
23+
target_family: Option<String>,
24+
target_os: String,
25+
target_string: String,
26+
target_vendor: String,
27+
target_features: Vec<String>,
28+
}
29+
30+
impl Config {
31+
fn from_env() -> Self {
32+
let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
33+
.map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
34+
.unwrap_or_default();
35+
36+
Self {
37+
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
38+
out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
39+
opt_level: env::var("OPT_LEVEL").unwrap().parse().unwrap(),
40+
target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
41+
target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
42+
target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
43+
target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
44+
target_string: env::var("TARGET").unwrap(),
45+
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
46+
target_features,
47+
}
48+
}
49+
}
50+
51+
/// Some tests are extremely slow. Emit a config option based on optimization level.
52+
fn emit_optimization_cfg(cfg: &Config) {
53+
println!("cargo::rustc-check-cfg=cfg(optimizations_enabled)");
54+
55+
if cfg.opt_level >= 2 {
56+
println!("cargo::rustc-cfg=optimizations_enabled");
57+
}
58+
}
59+
60+
/// Provide an alias for common longer config combinations.
61+
fn emit_cfg_shorthands(cfg: &Config) {
62+
println!("cargo::rustc-check-cfg=cfg(x86_no_sse)");
63+
if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
64+
// Shorthand to detect i586 targets
65+
println!("cargo::rustc-cfg=x86_no_sse");
66+
}
67+
}
68+
69+
/// Create a list of all source files in an array. This can be used for making sure that
70+
/// all functions are tested or otherwise covered in some way.
71+
// FIXME: it would probably be better to use rustdoc JSON output to get public functions.
72+
fn list_all_tests(cfg: &Config) {
73+
let math_src = cfg.manifest_dir.join("../../src/math");
74+
75+
let mut files = fs::read_dir(math_src)
76+
.unwrap()
77+
.map(|f| f.unwrap().path())
78+
.filter(|entry| entry.is_file())
79+
.map(|f| f.file_stem().unwrap().to_str().unwrap().to_owned())
80+
.collect::<Vec<_>>();
81+
files.sort();
82+
83+
let mut s = "pub const ALL_FUNCTIONS: &[&str] = &[".to_owned();
84+
for f in files {
85+
if f == "mod" {
86+
// skip mod.rs
87+
continue;
88+
}
89+
write!(s, "\"{f}\",").unwrap();
90+
}
91+
write!(s, "];").unwrap();
92+
93+
let outfile = cfg.out_dir.join("all_files.rs");
94+
fs::write(outfile, s).unwrap();
495
}
596

97+
/// At build time, generate the output of what the corresponding `*musl` target does with a range
98+
/// of inputs.
99+
///
100+
/// Serialize that target's output, run the same thing with our symbols, then load and compare
101+
/// the resulting values.
6102
#[cfg(feature = "test-musl-serialized")]
7-
mod musl_reference_tests {
103+
mod musl_serialized_tests {
8104
use std::path::PathBuf;
9105
use std::process::Command;
10106
use std::{env, fs};

crates/libm-test/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
1+
// List of all files present in libm's source
2+
include!(concat!(env!("OUT_DIR"), "/all_files.rs"));

0 commit comments

Comments
 (0)