rust/tests/run-make/print-cfg/rmake.rs
许杰友 Jieyou Xu (Joe) beaf9d1c14 tests/run-make: add missing needs-llvm-components
Without suitable `needs-llvm-components` directives, these tests that
rely on target-specific codegen can fail if used with a LLVM that is
built without the required components.
2024-08-26 18:20:32 +08:00

106 lines
3.1 KiB
Rust

//! This checks the output of `--print=cfg`
//!
//! Specifically it checks that output is correctly formatted
//! (ie. no duplicated cfgs, values are between "", names are not).
//!
//! It also checks that some targets have the correct set cfgs.
// ignore-tidy-linelength
//@ needs-llvm-components: arm x86
// Note: without the needs-llvm-components it will fail on LLVM built without the required
// components listed above.
use std::collections::HashSet;
use std::iter::FromIterator;
use std::path::PathBuf;
use run_make_support::{rfs, rustc};
struct PrintCfg {
target: &'static str,
includes: &'static [&'static str],
disallow: &'static [&'static str],
}
fn main() {
check(PrintCfg {
target: "x86_64-pc-windows-gnu",
includes: &["windows", "target_arch=\"x86_64\""],
disallow: &["unix"],
});
check(PrintCfg {
target: "i686-pc-windows-msvc",
includes: &["windows", "target_env=\"msvc\""],
disallow: &["unix"],
});
check(PrintCfg {
target: "i686-apple-darwin",
includes: &["unix", "target_os=\"macos\"", "target_vendor=\"apple\""],
disallow: &["windows"],
});
check(PrintCfg {
target: "i686-unknown-linux-gnu",
includes: &["unix", "target_env=\"gnu\""],
disallow: &["windows"],
});
check(PrintCfg {
target: "arm-unknown-linux-gnueabihf",
includes: &["unix", "target_abi=\"eabihf\""],
disallow: &["windows"],
});
}
fn check(PrintCfg { target, includes, disallow }: PrintCfg) {
fn check_(output: &str, includes: &[&str], disallow: &[&str]) {
let mut found = HashSet::<String>::new();
let mut recorded = HashSet::<String>::new();
for l in output.lines() {
assert!(l == l.trim());
if let Some((left, right)) = l.split_once('=') {
assert!(right.starts_with("\""));
assert!(right.ends_with("\""));
assert!(!left.contains("\""));
} else {
assert!(!l.contains("\""));
}
assert!(recorded.insert(l.to_string()), "duplicated: {}", &l);
assert!(!disallow.contains(&l), "found disallowed: {}", &l);
if includes.contains(&l) {
assert!(found.insert(l.to_string()), "duplicated (includes): {}", &l);
}
}
let should_found = HashSet::<String>::from_iter(includes.iter().map(|s| s.to_string()));
let diff: Vec<_> = should_found.difference(&found).collect();
assert!(
diff.is_empty(),
"expected: {:?}, found: {:?} (~ {:?})",
&should_found,
&found,
&diff
);
}
// --print=cfg
{
let output = rustc().target(target).print("cfg").run();
let stdout = output.stdout_utf8();
check_(&stdout, includes, disallow);
}
// --print=cfg=PATH
{
let tmp_path = PathBuf::from(format!("{target}.cfg"));
rustc().target(target).print(&format!("cfg={}", tmp_path.display())).run();
let output = rfs::read_to_string(&tmp_path);
check_(&output, includes, disallow);
}
}