Skip to content

Commit 0034d6c

Browse files
committed
Compile run-make recipes using the stage0 compiler
1 parent 4af94f8 commit 0034d6c

File tree

11 files changed

+78
-123
lines changed

11 files changed

+78
-123
lines changed

Diff for: src/bootstrap/src/core/build_steps/test.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
16791679
};
16801680

16811681
cmd.arg("--cargo-path").arg(cargo_path);
1682+
1683+
// We need to pass the compiler that was used to compile run-make-support,
1684+
// because we have to use the same compiler to compile rmake.rs recipes.
1685+
let stage0_rustc_path = builder.compiler(0, compiler.host);
1686+
cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path));
16821687
}
16831688

16841689
// Avoid depending on rustdoc when we don't need it.

Diff for: src/tools/compiletest/src/common.rs

+3
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ pub struct Config {
190190
/// The cargo executable.
191191
pub cargo_path: Option<PathBuf>,
192192

193+
/// Rustc executable used to compile run-make recipes.
194+
pub stage0_rustc_path: Option<PathBuf>,
195+
193196
/// The rustdoc executable.
194197
pub rustdoc_path: Option<PathBuf>,
195198

Diff for: src/tools/compiletest/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
5454
.reqopt("", "run-lib-path", "path to target shared libraries", "PATH")
5555
.reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH")
5656
.optopt("", "cargo-path", "path to cargo to use for compiling", "PATH")
57+
.optopt(
58+
"",
59+
"stage0-rustc-path",
60+
"path to rustc to use for compiling run-make recipes",
61+
"PATH",
62+
)
5763
.optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
5864
.optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
5965
.reqopt("", "python", "path to python to use for doc tests", "PATH")
@@ -320,6 +326,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
320326
run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
321327
rustc_path: opt_path(matches, "rustc-path"),
322328
cargo_path: matches.opt_str("cargo-path").map(PathBuf::from),
329+
stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(PathBuf::from),
323330
rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from),
324331
coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from),
325332
python: matches.opt_str("python").unwrap(),

Diff for: src/tools/compiletest/src/runtest/run_make.rs

+41-78
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ impl TestCx<'_> {
173173
fn run_rmake_v2_test(&self) {
174174
// For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe
175175
// (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust
176-
// library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`.
176+
// library and is available under
177+
// `build/$HOST/stage0-bootstrap-tools/$TARGET/release/librun_make_support.rlib`.
177178
//
178179
// 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support`
179180
// library.
@@ -224,25 +225,21 @@ impl TestCx<'_> {
224225
//
225226
// ```
226227
// build/<target_triple>/
227-
// ├── stageN-tools-bin/
228-
// │ └── librun_make_support.rlib // <- support rlib itself
229-
// ├── stageN-tools/
230-
// │ ├── release/deps/ // <- deps of deps
231-
// │ └── <host_triple>/release/deps/ // <- deps
228+
// ├── stage0-bootstrap-tools/
229+
// │ ├── <host_triple>/release/librun_make_support.rlib // <- support rlib itself
230+
// │ ├── <host_triple>/release/deps/ // <- deps
231+
// │ └── release/deps/ // <- deps of deps
232232
// ```
233233
//
234234
// FIXME(jieyouxu): there almost certainly is a better way to do this (specifically how the
235-
// support lib and its deps are organized, can't we copy them to the tools-bin dir as
236-
// well?), but this seems to work for now.
235+
// support lib and its deps are organized), but this seems to work for now.
237236

238-
let stage_number = self.config.stage;
237+
let tools_bin = host_build_root.join("stage0-bootstrap-tools");
238+
let support_host_path = tools_bin.join(&self.config.host).join("release");
239+
let support_lib_path = support_host_path.join("librun_make_support.rlib");
239240

240-
let stage_tools_bin = host_build_root.join(format!("stage{stage_number}-tools-bin"));
241-
let support_lib_path = stage_tools_bin.join("librun_make_support.rlib");
242-
243-
let stage_tools = host_build_root.join(format!("stage{stage_number}-tools"));
244-
let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps");
245-
let support_lib_deps_deps = stage_tools.join("release").join("deps");
241+
let support_lib_deps = support_host_path.join("deps");
242+
let support_lib_deps_deps = tools_bin.join("release").join("deps");
246243

247244
// To compile the recipe with rustc, we need to provide suitable dynamic library search
248245
// paths to rustc. This includes both:
@@ -253,12 +250,6 @@ impl TestCx<'_> {
253250
let base_dylib_search_paths =
254251
Vec::from_iter(env::split_paths(&env::var(dylib_env_var()).unwrap()));
255252

256-
let host_dylib_search_paths = {
257-
let mut paths = vec![self.config.compile_lib_path.clone()];
258-
paths.extend(base_dylib_search_paths.iter().cloned());
259-
paths
260-
};
261-
262253
// Calculate the paths of the recipe binary. As previously discussed, this is placed at
263254
// `<base_dir>/<bin_name>` with `bin_name` being `rmake` or `rmake.exe` depending on
264255
// platform.
@@ -268,7 +259,15 @@ impl TestCx<'_> {
268259
p
269260
};
270261

271-
let mut rustc = Command::new(&self.config.rustc_path);
262+
// run-make-support and run-make tests are compiled using the stage0 compiler
263+
// If the stage is 0, then the compiler that we test (either bootstrap or an explicitly
264+
// set compiler) is the one that actually compiled run-make-support.
265+
let stage0_rustc = self
266+
.config
267+
.stage0_rustc_path
268+
.as_ref()
269+
.expect("stage0 rustc is required to run run-make tests");
270+
let mut rustc = Command::new(&stage0_rustc);
272271
rustc
273272
.arg("-o")
274273
.arg(&recipe_bin)
@@ -282,35 +281,12 @@ impl TestCx<'_> {
282281
.arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
283282
.arg("--edition=2021")
284283
.arg(&self.testpaths.file.join("rmake.rs"))
285-
.arg("-Cprefer-dynamic")
286-
// Provide necessary library search paths for rustc.
287-
.env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
284+
.arg("-Cprefer-dynamic");
288285

289286
// In test code we want to be very pedantic about values being silently discarded that are
290287
// annotated with `#[must_use]`.
291288
rustc.arg("-Dunused_must_use");
292289

293-
// > `cg_clif` uses `COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0` for running the rustc
294-
// > test suite. With the introduction of rmake.rs this broke. `librun_make_support.rlib` is
295-
// > compiled using the bootstrap rustc wrapper which sets `--sysroot
296-
// > build/aarch64-unknown-linux-gnu/stage0-sysroot`, but then compiletest will compile
297-
// > `rmake.rs` using the sysroot of the bootstrap compiler causing it to not find the
298-
// > `libstd.rlib` against which `librun_make_support.rlib` is compiled.
299-
//
300-
// The gist here is that we have to pass the proper stage0 sysroot if we want
301-
//
302-
// ```
303-
// $ COMPILETEST_FORCE_STAGE0=1 ./x test run-make --stage 0
304-
// ```
305-
//
306-
// to work correctly.
307-
//
308-
// See <https://github.com/rust-lang/rust/pull/122248> for more background.
309-
let stage0_sysroot = host_build_root.join("stage0-sysroot");
310-
if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
311-
rustc.arg("--sysroot").arg(&stage0_sysroot);
312-
}
313-
314290
// Now run rustc to build the recipe.
315291
let res = self.run_command_to_procres(&mut rustc);
316292
if !res.status.success() {
@@ -320,35 +296,24 @@ impl TestCx<'_> {
320296
// To actually run the recipe, we have to provide the recipe with a bunch of information
321297
// provided through env vars.
322298

323-
// Compute stage-specific standard library paths.
324-
let stage_std_path = host_build_root.join(format!("stage{stage_number}")).join("lib");
325-
326299
// Compute dynamic library search paths for recipes.
300+
// These dylib directories are needed to **execute the recipe**.
327301
let recipe_dylib_search_paths = {
328302
let mut paths = base_dylib_search_paths.clone();
329-
330-
// For stage 0, we need to explicitly include the stage0-sysroot libstd dylib.
331-
// See <https://github.com/rust-lang/rust/issues/135373>.
332-
if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
333-
paths.push(
334-
stage0_sysroot.join("lib").join("rustlib").join(&self.config.host).join("lib"),
335-
);
336-
}
337-
338-
paths.push(support_lib_path.parent().unwrap().to_path_buf());
339-
paths.push(stage_std_path.join("rustlib").join(&self.config.host).join("lib"));
340-
paths
341-
};
342-
343-
// Compute runtime library search paths for recipes. This is target-specific.
344-
let target_runtime_dylib_search_paths = {
345-
let mut paths = vec![rmake_out_dir.clone()];
346-
paths.extend(base_dylib_search_paths.iter().cloned());
303+
paths.push(
304+
stage0_rustc
305+
.parent()
306+
.unwrap()
307+
.parent()
308+
.unwrap()
309+
.join("lib")
310+
.join("rustlib")
311+
.join(&self.config.host)
312+
.join("lib"),
313+
);
347314
paths
348315
};
349316

350-
// FIXME(jieyouxu): please rename `TARGET_RPATH_ENV`, `HOST_RPATH_DIR` and
351-
// `TARGET_RPATH_DIR`, it is **extremely** confusing!
352317
let mut cmd = Command::new(&recipe_bin);
353318
cmd.current_dir(&rmake_out_dir)
354319
.stdout(Stdio::piped())
@@ -357,9 +322,14 @@ impl TestCx<'_> {
357322
// example, this could be `LD_LIBRARY_PATH` on some linux distros but `PATH` on Windows.
358323
.env("LD_LIB_PATH_ENVVAR", dylib_env_var())
359324
// Provide the dylib search paths.
325+
// This is required to run the **recipe** itself.
360326
.env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap())
361-
// Provide runtime dylib search paths.
362-
.env("TARGET_RPATH_ENV", &env::join_paths(target_runtime_dylib_search_paths).unwrap())
327+
// Provide the directory to libraries that are needed to run the *compiler* invoked
328+
// by the recipe.
329+
.env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path)
330+
// Provide the directory to libraries that might be needed to run binaries created
331+
// by a compiler invoked by the recipe.
332+
.env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path)
363333
// Provide the target.
364334
.env("TARGET", &self.config.target)
365335
// Some tests unfortunately still need Python, so provide path to a Python interpreter.
@@ -370,13 +340,6 @@ impl TestCx<'_> {
370340
.env("BUILD_ROOT", &host_build_root)
371341
// Provide path to stage-corresponding rustc.
372342
.env("RUSTC", &self.config.rustc_path)
373-
// Provide the directory to libraries that are needed to run the *compiler*. This is not
374-
// to be confused with `TARGET_RPATH_ENV` or `TARGET_RPATH_DIR`. This is needed if the
375-
// recipe wants to invoke rustc.
376-
.env("HOST_RPATH_DIR", &self.config.compile_lib_path)
377-
// Provide the directory to libraries that might be needed to run compiled binaries
378-
// (further compiled by the recipe!).
379-
.env("TARGET_RPATH_DIR", &self.config.run_lib_path)
380343
// Provide which LLVM components are available (e.g. which LLVM components are provided
381344
// through a specific CI runner).
382345
.env("LLVM_COMPONENTS", &self.config.llvm_components);

Diff for: src/tools/run-make-support/src/external_deps/rustc.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::str::FromStr as _;
55
use crate::command::Command;
66
use crate::env::env_var;
77
use crate::path_helpers::cwd;
8-
use crate::util::set_host_rpath;
8+
use crate::util::set_host_compiler_dylib_path;
99
use crate::{is_aix, is_darwin, is_msvc, is_windows, uname};
1010

1111
/// Construct a new `rustc` invocation. This will automatically set the library
@@ -15,8 +15,8 @@ pub fn rustc() -> Rustc {
1515
Rustc::new()
1616
}
1717

18-
/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`]
19-
/// still presets the environment variable `HOST_RPATH_DIR` by default.
18+
/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_compiler_dylib_path`]
19+
/// still presets the environment variable `HOST_RUSTC_DYLIB_PATH` by default.
2020
#[track_caller]
2121
pub fn bare_rustc() -> Rustc {
2222
Rustc::bare()
@@ -44,7 +44,7 @@ pub fn rustc_path() -> String {
4444
#[track_caller]
4545
fn setup_common() -> Command {
4646
let mut cmd = Command::new(rustc_path());
47-
set_host_rpath(&mut cmd);
47+
set_host_compiler_dylib_path(&mut cmd);
4848
cmd
4949
}
5050

Diff for: src/tools/run-make-support/src/external_deps/rustdoc.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@ use std::ffi::OsStr;
22
use std::path::Path;
33

44
use crate::command::Command;
5-
use crate::env::{env_var, env_var_os};
6-
use crate::util::set_host_rpath;
5+
use crate::env::env_var;
6+
use crate::util::set_host_compiler_dylib_path;
77

8-
/// Construct a plain `rustdoc` invocation with no flags set.
9-
#[track_caller]
10-
pub fn bare_rustdoc() -> Rustdoc {
11-
Rustdoc::bare()
12-
}
13-
14-
/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
8+
/// Construct a new `rustdoc` invocation.
159
#[track_caller]
1610
pub fn rustdoc() -> Rustdoc {
1711
Rustdoc::new()
@@ -29,23 +23,15 @@ crate::macros::impl_common_helpers!(Rustdoc);
2923
fn setup_common() -> Command {
3024
let rustdoc = env_var("RUSTDOC");
3125
let mut cmd = Command::new(rustdoc);
32-
set_host_rpath(&mut cmd);
26+
set_host_compiler_dylib_path(&mut cmd);
3327
cmd
3428
}
3529

3630
impl Rustdoc {
3731
/// Construct a bare `rustdoc` invocation.
3832
#[track_caller]
39-
pub fn bare() -> Self {
40-
let cmd = setup_common();
41-
Self { cmd }
42-
}
43-
44-
/// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
45-
#[track_caller]
4633
pub fn new() -> Self {
47-
let mut cmd = setup_common();
48-
cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR"));
34+
let cmd = setup_common();
4935
Self { cmd }
5036
}
5137

Diff for: src/tools/run-make-support/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub use llvm::{
6767
};
6868
pub use python::python_command;
6969
pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
70-
pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
70+
pub use rustdoc::{rustdoc, Rustdoc};
7171

7272
/// [`diff`][mod@diff] is implemented in terms of the [similar] library.
7373
///

Diff for: src/tools/run-make-support/src/run.rs

+5-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::ffi::OsStr;
2-
use std::path::{Path, PathBuf};
2+
use std::path::PathBuf;
33
use std::{env, panic};
44

55
use crate::command::{Command, CompletedProcess};
6-
use crate::util::{handle_failed_output, set_host_rpath};
7-
use crate::{cwd, env_var, is_windows};
6+
use crate::util::handle_failed_output;
7+
use crate::{cwd, env_var};
88

99
#[track_caller]
1010
fn run_common(name: &str, args: Option<&[&str]>) -> Command {
@@ -18,10 +18,11 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
1818
cmd.arg(arg);
1919
}
2020
}
21+
2122
cmd.env(&ld_lib_path_envvar, {
2223
let mut paths = vec![];
2324
paths.push(cwd());
24-
for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) {
25+
for p in env::split_paths(&env_var("TARGET_EXE_DYLIB_PATH")) {
2526
paths.push(p.to_path_buf());
2627
}
2728
for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
@@ -31,15 +32,6 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
3132
});
3233
cmd.env("LC_ALL", "C"); // force english locale
3334

34-
if is_windows() {
35-
let mut paths = vec![];
36-
for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
37-
paths.push(p.to_path_buf());
38-
}
39-
paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf());
40-
cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
41-
}
42-
4335
cmd
4436
}
4537

@@ -84,7 +76,6 @@ pub fn run_fail(name: &str) -> CompletedProcess {
8476
#[track_caller]
8577
pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command {
8678
let mut command = Command::new(program);
87-
set_host_rpath(&mut command);
8879
command.env("LC_ALL", "C"); // force english locale
8980
command
9081
}

Diff for: src/tools/run-make-support/src/util.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ pub(crate) fn handle_failed_output(
2424
std::process::exit(1)
2525
}
2626

27-
/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
28-
pub(crate) fn set_host_rpath(cmd: &mut Command) {
27+
/// Set the runtime library paths as needed for running the host compilers (rustc/rustdoc/etc).
28+
pub(crate) fn set_host_compiler_dylib_path(cmd: &mut Command) {
2929
let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
3030
cmd.env(&ld_lib_path_envvar, {
3131
let mut paths = vec![];
3232
paths.push(cwd());
33-
paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
33+
paths.push(PathBuf::from(env_var("HOST_RUSTC_DYLIB_PATH")));
3434
for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) {
3535
paths.push(p.to_path_buf());
3636
}

Diff for: tests/run-make/rustdoc-default-output/rmake.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
// ensures the output of rustdoc's help menu is as expected.
44
// See https://github.com/rust-lang/rust/issues/88756
55

6-
use run_make_support::{bare_rustdoc, diff};
6+
use run_make_support::{diff, rustdoc};
77

88
fn main() {
9-
let out = bare_rustdoc().run().stdout_utf8();
9+
let out = rustdoc().run().stdout_utf8();
1010
diff()
1111
.expected_file("output-default.stdout")
1212
.actual_text("actual", out)

0 commit comments

Comments
 (0)