Skip to content

Commit fa3ef0c

Browse files
committed
Auto merge of rust-lang#113026 - jieyouxu:run-make-v2, r=bjorn3
Introduce `run-make` V2 infrastructure, a `run_make_support` library and port over 2 tests as example See [issue rust-lang#40713: Switch run-make tests from Makefiles to rust](rust-lang#40713) for more context. ### Basic Description of `run-make` V2 `run-make` V2 aims to eliminate the dependency on `make` and `Makefile`s for building `run-make`-style tests. Makefiles are replaced by *recipes* (`rmake.rs`). The current implementation runs `run-make` V2 tests in 3 steps: 1. We build the support library `run_make_support` which the `rmake.rs` recipes depend on as a tool dylib. 2. We build the recipe `rmake.rs` and link in the support library. 3. We run the recipe to build and run the tests. `rmake.rs` is basically a replacement for `Makefile`, and allows running arbitrary Rust code. ### Planned Changes - [x] Get rid of the builder style patterns in `rmake_support` and instead use something like ```rust let output = rustc!(scx, "--cfg x -Cprefer-dynamic -Csymbol-mangling-version=legacy - Zunstable-options"); ``` as per Nils' suggestion. This can probably use something like `xshell`. - [x] Make `run_make_support` into a proper crate so it can have external dependencies like `xshell`. - [x] Instead of having an entire alternative directory `run-make-v2`, change how V2 tests are collected based on presence of `rmake.rs` recipe file. This should ease migration and prevent git history from being messed up by big moves. ### Disclaimer The current implementation is very much a **very very rough prototype** just to get the 2 example tests working. I would appreciate any feedback on the design and implementation.
2 parents ee9c7c9 + 2056e61 commit fa3ef0c

File tree

11 files changed

+483
-32
lines changed

11 files changed

+483
-32
lines changed

Cargo.lock

+13
Original file line numberDiff line numberDiff line change
@@ -3352,6 +3352,13 @@ dependencies = [
33523352
"serde_json",
33533353
]
33543354

3355+
[[package]]
3356+
name = "run_make_support"
3357+
version = "0.0.0"
3358+
dependencies = [
3359+
"shell-words",
3360+
]
3361+
33553362
[[package]]
33563363
name = "rust-demangler"
33573364
version = "0.0.1"
@@ -5063,6 +5070,12 @@ version = "0.1.5"
50635070
source = "registry+https://github.com/rust-lang/crates.io-index"
50645071
checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
50655072

5073+
[[package]]
5074+
name = "shell-words"
5075+
version = "1.1.0"
5076+
source = "registry+https://github.com/rust-lang/crates.io-index"
5077+
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
5078+
50665079
[[package]]
50675080
name = "shlex"
50685081
version = "1.3.0"

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ members = [
1010
"src/tools/clippy",
1111
"src/tools/clippy/clippy_dev",
1212
"src/tools/compiletest",
13+
"src/tools/run-make-support",
1314
"src/tools/error_index_generator",
1415
"src/tools/linkchecker",
1516
"src/tools/lint-docs",

src/bootstrap/src/core/build_steps/test.rs

+80-1
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,52 @@ macro_rules! coverage_test_alias {
13271327
};
13281328
}
13291329

1330+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
1331+
pub struct RunMakeSupport {
1332+
pub compiler: Compiler,
1333+
pub target: TargetSelection,
1334+
}
1335+
1336+
impl Step for RunMakeSupport {
1337+
type Output = PathBuf;
1338+
const DEFAULT: bool = true;
1339+
1340+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
1341+
run.never()
1342+
}
1343+
1344+
fn make_run(run: RunConfig<'_>) {
1345+
let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
1346+
run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() });
1347+
}
1348+
1349+
fn run(self, builder: &Builder<'_>) -> PathBuf {
1350+
builder.ensure(compile::Std::new(self.compiler, self.target));
1351+
1352+
let cargo = tool::prepare_tool_cargo(
1353+
builder,
1354+
self.compiler,
1355+
Mode::ToolStd,
1356+
self.target,
1357+
"build",
1358+
"src/tools/run-make-support",
1359+
SourceType::InTree,
1360+
&[],
1361+
);
1362+
1363+
let mut cargo = Command::from(cargo);
1364+
builder.run(&mut cargo);
1365+
1366+
let lib_name = "librun_make_support.rlib";
1367+
let lib = builder.tools_dir(self.compiler).join(&lib_name);
1368+
1369+
let cargo_out =
1370+
builder.cargo_out(self.compiler, Mode::ToolStd, self.target).join(&lib_name);
1371+
builder.copy(&cargo_out, &lib);
1372+
lib
1373+
}
1374+
}
1375+
13301376
default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" });
13311377

13321378
default_test!(RunPassValgrind {
@@ -1361,7 +1407,40 @@ host_test!(RustdocJson { path: "tests/rustdoc-json", mode: "rustdoc-json", suite
13611407

13621408
host_test!(Pretty { path: "tests/pretty", mode: "pretty", suite: "pretty" });
13631409

1364-
default_test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make" });
1410+
// Special-handling is needed for `run-make`, so don't use `default_test` for defining `RunMake`
1411+
// tests.
1412+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1413+
pub struct RunMake {
1414+
pub compiler: Compiler,
1415+
pub target: TargetSelection,
1416+
}
1417+
1418+
impl Step for RunMake {
1419+
type Output = ();
1420+
const DEFAULT: bool = true;
1421+
const ONLY_HOSTS: bool = false;
1422+
1423+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
1424+
run.suite_path("tests/run-make")
1425+
}
1426+
1427+
fn make_run(run: RunConfig<'_>) {
1428+
let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
1429+
run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() });
1430+
run.builder.ensure(RunMake { compiler, target: run.target });
1431+
}
1432+
1433+
fn run(self, builder: &Builder<'_>) {
1434+
builder.ensure(Compiletest {
1435+
compiler: self.compiler,
1436+
target: self.target,
1437+
mode: "run-make",
1438+
suite: "run-make",
1439+
path: "tests/run-make",
1440+
compare_mode: None,
1441+
});
1442+
}
1443+
}
13651444

13661445
host_test!(RunMakeFullDeps {
13671446
path: "tests/run-make-fulldeps",

src/tools/compiletest/src/lib.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -655,13 +655,21 @@ fn collect_tests_from_dir(
655655
return Ok(());
656656
}
657657

658-
if config.mode == Mode::RunMake && dir.join("Makefile").exists() {
659-
let paths = TestPaths {
660-
file: dir.to_path_buf(),
661-
relative_dir: relative_dir_path.parent().unwrap().to_path_buf(),
662-
};
663-
tests.extend(make_test(config, cache, &paths, inputs, poisoned));
664-
return Ok(());
658+
if config.mode == Mode::RunMake {
659+
if dir.join("Makefile").exists() && dir.join("rmake.rs").exists() {
660+
return Err(io::Error::other(
661+
"run-make tests cannot have both `Makefile` and `rmake.rs`",
662+
));
663+
}
664+
665+
if dir.join("Makefile").exists() || dir.join("rmake.rs").exists() {
666+
let paths = TestPaths {
667+
file: dir.to_path_buf(),
668+
relative_dir: relative_dir_path.parent().unwrap().to_path_buf(),
669+
};
670+
tests.extend(make_test(config, cache, &paths, inputs, poisoned));
671+
return Ok(());
672+
}
665673
}
666674

667675
// If we find a test foo/bar.rs, we have to build the
@@ -733,8 +741,17 @@ fn make_test(
733741
poisoned: &mut bool,
734742
) -> Vec<test::TestDescAndFn> {
735743
let test_path = if config.mode == Mode::RunMake {
736-
// Parse directives in the Makefile
737-
testpaths.file.join("Makefile")
744+
if testpaths.file.join("rmake.rs").exists() && testpaths.file.join("Makefile").exists() {
745+
panic!("run-make tests cannot have both `rmake.rs` and `Makefile`");
746+
}
747+
748+
if testpaths.file.join("rmake.rs").exists() {
749+
// Parse directives in rmake.rs.
750+
testpaths.file.join("rmake.rs")
751+
} else {
752+
// Parse directives in the Makefile.
753+
testpaths.file.join("Makefile")
754+
}
738755
} else {
739756
PathBuf::from(&testpaths.file)
740757
};

0 commit comments

Comments
 (0)