compiletest: remove legacy Makefile-based run-make support
This commit is contained in:
parent
8c392966a0
commit
3998690a68
4 changed files with 18 additions and 214 deletions
|
|
@ -709,11 +709,11 @@ impl TestProps {
|
|||
/// returns a struct containing various parts of the directive.
|
||||
fn line_directive<'line>(
|
||||
line_number: usize,
|
||||
comment: &str,
|
||||
original_line: &'line str,
|
||||
) -> Option<DirectiveLine<'line>> {
|
||||
// Ignore lines that don't start with the comment prefix.
|
||||
let after_comment = original_line.trim_start().strip_prefix(comment)?.trim_start();
|
||||
let after_comment =
|
||||
original_line.trim_start().strip_prefix(COMPILETEST_DIRECTIVE_PREFIX)?.trim_start();
|
||||
|
||||
let revision;
|
||||
let raw_directive;
|
||||
|
|
@ -722,7 +722,7 @@ fn line_directive<'line>(
|
|||
// A comment like `//@[foo]` only applies to revision `foo`.
|
||||
let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else {
|
||||
panic!(
|
||||
"malformed condition directive: expected `{comment}[foo]`, found `{original_line}`"
|
||||
"malformed condition directive: expected `{COMPILETEST_DIRECTIVE_PREFIX}[foo]`, found `{original_line}`"
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -836,6 +836,8 @@ pub(crate) fn check_directive<'a>(
|
|||
CheckDirectiveResult { is_known_directive: is_known(&directive_name), trailing_directive }
|
||||
}
|
||||
|
||||
const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";
|
||||
|
||||
fn iter_header(
|
||||
mode: Mode,
|
||||
_suite: &str,
|
||||
|
|
@ -849,8 +851,7 @@ fn iter_header(
|
|||
}
|
||||
|
||||
// Coverage tests in coverage-run mode always have these extra directives, without needing to
|
||||
// specify them manually in every test file. (Some of the comments below have been copied over
|
||||
// from the old `tests/run-make/coverage-reports/Makefile`, which no longer exists.)
|
||||
// specify them manually in every test file.
|
||||
//
|
||||
// FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later.
|
||||
if mode == Mode::CoverageRun {
|
||||
|
|
@ -867,9 +868,6 @@ fn iter_header(
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE(jieyouxu): once we get rid of `Makefile`s we can unconditionally check for `//@`.
|
||||
let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//@" } else { "#" };
|
||||
|
||||
let mut rdr = BufReader::with_capacity(1024, rdr);
|
||||
let mut ln = String::new();
|
||||
let mut line_number = 0;
|
||||
|
|
@ -882,7 +880,7 @@ fn iter_header(
|
|||
}
|
||||
let ln = ln.trim();
|
||||
|
||||
let Some(directive_line) = line_directive(line_number, comment, ln) else {
|
||||
let Some(directive_line) = line_directive(line_number, ln) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -239,11 +239,6 @@ fn check_ignore(config: &Config, contents: &str) -> bool {
|
|||
d.ignore
|
||||
}
|
||||
|
||||
fn parse_makefile(config: &Config, contents: &str) -> EarlyProps {
|
||||
let bytes = contents.as_bytes();
|
||||
EarlyProps::from_reader(config, Path::new("Makefile"), bytes)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_fail() {
|
||||
let config: Config = cfg().build();
|
||||
|
|
@ -261,10 +256,6 @@ fn revisions() {
|
|||
let config: Config = cfg().build();
|
||||
|
||||
assert_eq!(parse_rs(&config, "//@ revisions: a b c").revisions, vec!["a", "b", "c"],);
|
||||
assert_eq!(
|
||||
parse_makefile(&config, "# revisions: hello there").revisions,
|
||||
vec!["hello", "there"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub mod util;
|
|||
|
||||
use core::panic;
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::ffi::OsString;
|
||||
use std::io::{self, ErrorKind};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
|
|
@ -268,12 +268,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
let path = Path::new(f);
|
||||
let mut iter = path.iter().skip(1);
|
||||
|
||||
// We skip the test folder and check if the user passed `rmake.rs` or `Makefile`.
|
||||
if iter
|
||||
.next()
|
||||
.is_some_and(|s| s == OsStr::new("rmake.rs") || s == OsStr::new("Makefile"))
|
||||
&& iter.next().is_none()
|
||||
{
|
||||
// We skip the test folder and check if the user passed `rmake.rs`.
|
||||
if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() {
|
||||
path.parent().unwrap().to_str().unwrap().to_string()
|
||||
} else {
|
||||
f.to_string()
|
||||
|
|
@ -776,16 +772,9 @@ fn collect_tests_from_dir(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
// For run-make tests, a "test file" is actually a directory that contains
|
||||
// an `rmake.rs` or `Makefile`"
|
||||
// For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`.
|
||||
if cx.config.mode == Mode::RunMake {
|
||||
if dir.join("Makefile").exists() && dir.join("rmake.rs").exists() {
|
||||
return Err(io::Error::other(
|
||||
"run-make tests cannot have both `Makefile` and `rmake.rs`",
|
||||
));
|
||||
}
|
||||
|
||||
if dir.join("Makefile").exists() || dir.join("rmake.rs").exists() {
|
||||
if dir.join("rmake.rs").exists() {
|
||||
let paths = TestPaths {
|
||||
file: dir.to_path_buf(),
|
||||
relative_dir: relative_dir_path.parent().unwrap().to_path_buf(),
|
||||
|
|
@ -854,24 +843,14 @@ pub fn is_test(file_name: &OsString) -> bool {
|
|||
!invalid_prefixes.iter().any(|p| file_name.starts_with(p))
|
||||
}
|
||||
|
||||
/// For a single test file, creates one or more test structures (one per revision)
|
||||
/// that can be handed over to libtest to run, possibly in parallel.
|
||||
/// For a single test file, creates one or more test structures (one per revision) that can be
|
||||
/// handed over to libtest to run, possibly in parallel.
|
||||
fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &TestPaths) {
|
||||
// For run-make tests, each "test file" is actually a _directory_ containing
|
||||
// an `rmake.rs` or `Makefile`. But for the purposes of directive parsing,
|
||||
// we want to look at that recipe file, not the directory itself.
|
||||
// For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But
|
||||
// for the purposes of directive parsing, we want to look at that recipe file, not the directory
|
||||
// itself.
|
||||
let test_path = if cx.config.mode == Mode::RunMake {
|
||||
if testpaths.file.join("rmake.rs").exists() && testpaths.file.join("Makefile").exists() {
|
||||
panic!("run-make tests cannot have both `rmake.rs` and `Makefile`");
|
||||
}
|
||||
|
||||
if testpaths.file.join("rmake.rs").exists() {
|
||||
// Parse directives in rmake.rs.
|
||||
testpaths.file.join("rmake.rs")
|
||||
} else {
|
||||
// Parse directives in the Makefile.
|
||||
testpaths.file.join("Makefile")
|
||||
}
|
||||
testpaths.file.join("rmake.rs")
|
||||
} else {
|
||||
PathBuf::from(&testpaths.file)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,168 +9,6 @@ use crate::util::{copy_dir_all, dylib_env_var};
|
|||
|
||||
impl TestCx<'_> {
|
||||
pub(super) fn run_rmake_test(&self) {
|
||||
let test_dir = &self.testpaths.file;
|
||||
if test_dir.join("rmake.rs").exists() {
|
||||
self.run_rmake_v2_test();
|
||||
} else if test_dir.join("Makefile").exists() {
|
||||
self.run_rmake_legacy_test();
|
||||
} else {
|
||||
self.fatal("failed to find either `rmake.rs` or `Makefile`")
|
||||
}
|
||||
}
|
||||
|
||||
fn run_rmake_legacy_test(&self) {
|
||||
let cwd = env::current_dir().unwrap();
|
||||
|
||||
// FIXME(Zalathar): This should probably be `output_base_dir` to avoid
|
||||
// an unnecessary extra subdirectory, but since legacy Makefile tests
|
||||
// are hopefully going away, it seems safer to leave this perilous code
|
||||
// as-is until it can all be deleted.
|
||||
let tmpdir = cwd.join(self.output_base_name());
|
||||
ignore_not_found(|| recursive_remove(&tmpdir)).unwrap();
|
||||
|
||||
fs::create_dir_all(&tmpdir).unwrap();
|
||||
|
||||
let host = &self.config.host;
|
||||
let make = if host.contains("dragonfly")
|
||||
|| host.contains("freebsd")
|
||||
|| host.contains("netbsd")
|
||||
|| host.contains("openbsd")
|
||||
|| host.contains("aix")
|
||||
{
|
||||
"gmake"
|
||||
} else {
|
||||
"make"
|
||||
};
|
||||
|
||||
let mut cmd = Command::new(make);
|
||||
cmd.current_dir(&self.testpaths.file)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.env("TARGET", &self.config.target)
|
||||
.env("PYTHON", &self.config.python)
|
||||
.env("S", &self.config.src_root)
|
||||
.env("RUST_BUILD_STAGE", &self.config.stage_id)
|
||||
.env("RUSTC", cwd.join(&self.config.rustc_path))
|
||||
.env("TMPDIR", &tmpdir)
|
||||
.env("LD_LIB_PATH_ENVVAR", dylib_env_var())
|
||||
.env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
|
||||
.env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
|
||||
.env("LLVM_COMPONENTS", &self.config.llvm_components)
|
||||
// We for sure don't want these tests to run in parallel, so make
|
||||
// sure they don't have access to these vars if we run via `make`
|
||||
// at the top level
|
||||
.env_remove("MAKEFLAGS")
|
||||
.env_remove("MFLAGS")
|
||||
.env_remove("CARGO_MAKEFLAGS");
|
||||
|
||||
if let Some(ref cargo) = self.config.cargo_path {
|
||||
cmd.env("CARGO", cwd.join(cargo));
|
||||
}
|
||||
|
||||
if let Some(ref rustdoc) = self.config.rustdoc_path {
|
||||
cmd.env("RUSTDOC", cwd.join(rustdoc));
|
||||
}
|
||||
|
||||
if let Some(ref node) = self.config.nodejs {
|
||||
cmd.env("NODE", node);
|
||||
}
|
||||
|
||||
if let Some(ref linker) = self.config.target_linker {
|
||||
cmd.env("RUSTC_LINKER", linker);
|
||||
}
|
||||
|
||||
if let Some(ref clang) = self.config.run_clang_based_tests_with {
|
||||
cmd.env("CLANG", clang);
|
||||
}
|
||||
|
||||
if let Some(ref filecheck) = self.config.llvm_filecheck {
|
||||
cmd.env("LLVM_FILECHECK", filecheck);
|
||||
}
|
||||
|
||||
if let Some(ref llvm_bin_dir) = self.config.llvm_bin_dir {
|
||||
cmd.env("LLVM_BIN_DIR", llvm_bin_dir);
|
||||
}
|
||||
|
||||
if let Some(ref remote_test_client) = self.config.remote_test_client {
|
||||
cmd.env("REMOTE_TEST_CLIENT", remote_test_client);
|
||||
}
|
||||
|
||||
// We don't want RUSTFLAGS set from the outside to interfere with
|
||||
// compiler flags set in the test cases:
|
||||
cmd.env_remove("RUSTFLAGS");
|
||||
|
||||
// Use dynamic musl for tests because static doesn't allow creating dylibs
|
||||
if self.config.host.contains("musl") {
|
||||
cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static").env("IS_MUSL_HOST", "1");
|
||||
}
|
||||
|
||||
if self.config.bless {
|
||||
cmd.env("RUSTC_BLESS_TEST", "--bless");
|
||||
// Assume this option is active if the environment variable is "defined", with _any_ value.
|
||||
// As an example, a `Makefile` can use this option by:
|
||||
//
|
||||
// ifdef RUSTC_BLESS_TEST
|
||||
// cp "$(TMPDIR)"/actual_something.ext expected_something.ext
|
||||
// else
|
||||
// $(DIFF) expected_something.ext "$(TMPDIR)"/actual_something.ext
|
||||
// endif
|
||||
}
|
||||
|
||||
if self.config.target.contains("msvc") && !self.config.cc.is_empty() {
|
||||
// We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe`
|
||||
// and that `lib.exe` lives next to it.
|
||||
let lib = Path::new(&self.config.cc).parent().unwrap().join("lib.exe");
|
||||
|
||||
// MSYS doesn't like passing flags of the form `/foo` as it thinks it's
|
||||
// a path and instead passes `C:\msys64\foo`, so convert all
|
||||
// `/`-arguments to MSVC here to `-` arguments.
|
||||
let cflags = self
|
||||
.config
|
||||
.cflags
|
||||
.split(' ')
|
||||
.map(|s| s.replace("/", "-"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
let cxxflags = self
|
||||
.config
|
||||
.cxxflags
|
||||
.split(' ')
|
||||
.map(|s| s.replace("/", "-"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
|
||||
cmd.env("IS_MSVC", "1")
|
||||
.env("IS_WINDOWS", "1")
|
||||
.env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
|
||||
.env("MSVC_LIB_PATH", format!("{}", lib.display()))
|
||||
.env("CC", format!("'{}' {}", self.config.cc, cflags))
|
||||
.env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags));
|
||||
} else {
|
||||
cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
|
||||
.env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags))
|
||||
.env("AR", &self.config.ar);
|
||||
|
||||
if self.config.target.contains("windows") {
|
||||
cmd.env("IS_WINDOWS", "1");
|
||||
}
|
||||
}
|
||||
|
||||
let (output, truncated) =
|
||||
self.read2_abbreviated(cmd.spawn().expect("failed to spawn `make`"));
|
||||
if !output.status.success() {
|
||||
let res = ProcRes {
|
||||
status: output.status,
|
||||
stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
|
||||
stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
|
||||
truncated,
|
||||
cmdline: format!("{:?}", cmd),
|
||||
};
|
||||
self.fatal_proc_rec("make failed", &res);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_rmake_v2_test(&self) {
|
||||
// For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe
|
||||
// (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust
|
||||
// library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`.
|
||||
|
|
@ -191,8 +29,6 @@ impl TestCx<'_> {
|
|||
// recipes to `remove_dir_all($TMPDIR)` without running into issues related trying to remove
|
||||
// a currently running executable because the recipe executable is not under the
|
||||
// `rmake_out/` directory.
|
||||
//
|
||||
// This setup intentionally diverges from legacy Makefile run-make tests.
|
||||
let base_dir = self.output_base_dir();
|
||||
ignore_not_found(|| recursive_remove(&base_dir)).unwrap();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue