Skip to content

Commit 1f00719

Browse files
committed
Compile run-make recipes using the stage0 compiler
1 parent dc87948 commit 1f00719

File tree

7 files changed

+67
-116
lines changed

7 files changed

+67
-116
lines changed

src/tools/compiletest/src/common.rs

+5
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ pub struct Config {
205205
/// The jsondoclint executable.
206206
pub jsondoclint_path: Option<String>,
207207

208+
/// Path to a target directory where the run-make-support rlib library was built.
209+
/// We have to pass a path to the directory, because compiletest also resolves its transitive
210+
/// dependencies from there.
211+
pub run_make_support_dir: Option<PathBuf>,
212+
208213
/// The LLVM `FileCheck` binary path.
209214
pub llvm_filecheck: Option<PathBuf>,
210215

src/tools/compiletest/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
5959
.reqopt("", "python", "path to python to use for doc tests", "PATH")
6060
.optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH")
6161
.optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH")
62+
.optopt(
63+
"",
64+
"run-make-support-dir",
65+
"path to a directory with built run-make-support library used for run-make tests",
66+
"PATH",
67+
)
6268
.optopt("", "run-clang-based-tests-with", "path to Clang executable", "PATH")
6369
.optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
6470
.reqopt("", "src-base", "directory to scan for test files", "PATH")
@@ -311,6 +317,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
311317
python: matches.opt_str("python").unwrap(),
312318
jsondocck_path: matches.opt_str("jsondocck-path"),
313319
jsondoclint_path: matches.opt_str("jsondoclint-path"),
320+
run_make_support_dir: matches.opt_str("run-make-support-dir").map(PathBuf::from),
314321
run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"),
315322
llvm_filecheck: matches.opt_str("llvm-filecheck").map(PathBuf::from),
316323
llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from),

src/tools/compiletest/src/runtest/run_make.rs

+39-77
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ impl TestCx<'_> {
175175
fn run_rmake_v2_test(&self) {
176176
// For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe
177177
// (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust
178-
// library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`.
178+
// library and is available under
179+
// `build/$TARGET/stage0-bootstrap-tools/$HOST/release/librun_make_support.rlib`.
179180
//
180181
// 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support`
181182
// library.
@@ -249,25 +250,21 @@ impl TestCx<'_> {
249250
//
250251
// ```
251252
// build/<target_triple>/
252-
// ├── stageN-tools-bin/
253-
// │ └── librun_make_support.rlib // <- support rlib itself
254-
// ├── stageN-tools/
255-
// │ ├── release/deps/ // <- deps of deps
256-
// │ └── <host_triple>/release/deps/ // <- deps
253+
// ├── stage0-bootstrap-tools/
254+
// │ ├── <host_triple>/release/librun_make_support.rlib // <- support rlib itself
255+
// │ ├── <host_triple>/release/deps/ // <- deps
256+
// │ └── release/deps/ // <- deps of deps
257257
// ```
258258
//
259259
// FIXME(jieyouxu): there almost certainly is a better way to do this (specifically how the
260-
// support lib and its deps are organized, can't we copy them to the tools-bin dir as
261-
// well?), but this seems to work for now.
260+
// support lib and its deps are organized), but this seems to work for now.
262261

263-
let stage_number = self.config.stage;
262+
let tools_bin = build_root.join("stage0-bootstrap-tools");
263+
let support_host_path = tools_bin.join(&self.config.host).join("release");
264+
let support_lib_path = support_host_path.join("librun_make_support.rlib");
264265

265-
let stage_tools_bin = build_root.join(format!("stage{stage_number}-tools-bin"));
266-
let support_lib_path = stage_tools_bin.join("librun_make_support.rlib");
267-
268-
let stage_tools = build_root.join(format!("stage{stage_number}-tools"));
269-
let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps");
270-
let support_lib_deps_deps = stage_tools.join("release").join("deps");
266+
let support_lib_deps = support_host_path.join("deps");
267+
let support_lib_deps_deps = tools_bin.join("release").join("deps");
271268

272269
// To compile the recipe with rustc, we need to provide suitable dynamic library search
273270
// paths to rustc. This includes both:
@@ -278,12 +275,6 @@ impl TestCx<'_> {
278275
let base_dylib_search_paths =
279276
Vec::from_iter(env::split_paths(&env::var(dylib_env_var()).unwrap()));
280277

281-
let host_dylib_search_paths = {
282-
let mut paths = vec![self.config.compile_lib_path.clone()];
283-
paths.extend(base_dylib_search_paths.iter().cloned());
284-
paths
285-
};
286-
287278
// Calculate the paths of the recipe binary. As previously discussed, this is placed at
288279
// `<base_dir>/<bin_name>` with `bin_name` being `rmake` or `rmake.exe` depending on
289280
// platform.
@@ -293,7 +284,13 @@ impl TestCx<'_> {
293284
p
294285
};
295286

296-
let mut rustc = Command::new(&self.config.rustc_path);
287+
// run-make-support and run-make tests are compiled using the bootstrap compiler
288+
let bootstrap_rustc = {
289+
let mut p = build_root.join("stage0").join("bin").join("rustc");
290+
p.set_extension(env::consts::EXE_EXTENSION);
291+
p
292+
};
293+
let mut rustc = Command::new(bootstrap_rustc);
297294
rustc
298295
.arg("-o")
299296
.arg(&recipe_bin)
@@ -307,34 +304,14 @@ impl TestCx<'_> {
307304
.arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
308305
.arg("--edition=2021")
309306
.arg(&self.testpaths.file.join("rmake.rs"))
310-
.arg("-Cprefer-dynamic")
311-
// Provide necessary library search paths for rustc.
312-
.env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
307+
.arg("-Cprefer-dynamic");
313308

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

318-
// > `cg_clif` uses `COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0` for running the rustc
319-
// > test suite. With the introduction of rmake.rs this broke. `librun_make_support.rlib` is
320-
// > compiled using the bootstrap rustc wrapper which sets `--sysroot
321-
// > build/aarch64-unknown-linux-gnu/stage0-sysroot`, but then compiletest will compile
322-
// > `rmake.rs` using the sysroot of the bootstrap compiler causing it to not find the
323-
// > `libstd.rlib` against which `librun_make_support.rlib` is compiled.
324-
//
325-
// The gist here is that we have to pass the proper stage0 sysroot if we want
326-
//
327-
// ```
328-
// $ COMPILETEST_FORCE_STAGE0=1 ./x test run-make --stage 0
329-
// ```
330-
//
331-
// to work correctly.
332-
//
333-
// See <https://github.com/rust-lang/rust/pull/122248> for more background.
334-
let stage0_sysroot = build_root.join("stage0-sysroot");
335-
if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
336-
rustc.arg("--sysroot").arg(&stage0_sysroot);
337-
}
313+
// TODO: test COMPILETEST_FORCE_STAGE0=1 ./x test tests/run-make --stage 0
314+
// TODO: test ./x test tests/run-make
338315

339316
// Now run rustc to build the recipe.
340317
let res = self.run_command_to_procres(&mut rustc);
@@ -345,35 +322,22 @@ impl TestCx<'_> {
345322
// To actually run the recipe, we have to provide the recipe with a bunch of information
346323
// provided through env vars.
347324

348-
// Compute stage-specific standard library paths.
349-
let stage_std_path = build_root.join(format!("stage{stage_number}")).join("lib");
350-
351325
// Compute dynamic library search paths for recipes.
326+
// These dylib directories are needed to **execute the recipe**.
352327
let recipe_dylib_search_paths = {
353328
let mut paths = base_dylib_search_paths.clone();
354-
355-
// For stage 0, we need to explicitly include the stage0-sysroot libstd dylib.
356-
// See <https://github.com/rust-lang/rust/issues/135373>.
357-
if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
358-
paths.push(
359-
stage0_sysroot.join("lib").join("rustlib").join(&self.config.host).join("lib"),
360-
);
361-
}
362-
363-
paths.push(support_lib_path.parent().unwrap().to_path_buf());
364-
paths.push(stage_std_path.join("rustlib").join(&self.config.host).join("lib"));
365-
paths
366-
};
367-
368-
// Compute runtime library search paths for recipes. This is target-specific.
369-
let target_runtime_dylib_search_paths = {
370-
let mut paths = vec![rmake_out_dir.clone()];
371-
paths.extend(base_dylib_search_paths.iter().cloned());
329+
// This is the bootstrap stdlib required to run the rmake recipe itself
330+
paths.push(
331+
build_root
332+
.join("stage0")
333+
.join("lib")
334+
.join("rustlib")
335+
.join(&self.config.host)
336+
.join("lib"),
337+
);
372338
paths
373339
};
374340

375-
// FIXME(jieyouxu): please rename `TARGET_RPATH_ENV`, `HOST_RPATH_DIR` and
376-
// `TARGET_RPATH_DIR`, it is **extremely** confusing!
377341
let mut cmd = Command::new(&recipe_bin);
378342
cmd.current_dir(&rmake_out_dir)
379343
.stdout(Stdio::piped())
@@ -382,9 +346,14 @@ impl TestCx<'_> {
382346
// example, this could be `LD_LIBRARY_PATH` on some linux distros but `PATH` on Windows.
383347
.env("LD_LIB_PATH_ENVVAR", dylib_env_var())
384348
// Provide the dylib search paths.
349+
// This is required to run the **recipe** itself.
385350
.env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap())
386-
// Provide runtime dylib search paths.
387-
.env("TARGET_RPATH_ENV", &env::join_paths(target_runtime_dylib_search_paths).unwrap())
351+
// Provide the directory to libraries that are needed to run the *compiler* invoked
352+
// by the recipe.
353+
.env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path)
354+
// Provide the directory to libraries that might be needed to run binaries created
355+
// by a compiler invoked by the recipe.
356+
.env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path)
388357
// Provide the target.
389358
.env("TARGET", &self.config.target)
390359
// Some tests unfortunately still need Python, so provide path to a Python interpreter.
@@ -396,13 +365,6 @@ impl TestCx<'_> {
396365
.env("BUILD_ROOT", &build_root)
397366
// Provide path to stage-corresponding rustc.
398367
.env("RUSTC", &self.config.rustc_path)
399-
// Provide the directory to libraries that are needed to run the *compiler*. This is not
400-
// to be confused with `TARGET_RPATH_ENV` or `TARGET_RPATH_DIR`. This is needed if the
401-
// recipe wants to invoke rustc.
402-
.env("HOST_RPATH_DIR", &self.config.compile_lib_path)
403-
// Provide the directory to libraries that might be needed to run compiled binaries
404-
// (further compiled by the recipe!).
405-
.env("TARGET_RPATH_DIR", &self.config.run_lib_path)
406368
// Provide which LLVM components are available (e.g. which LLVM components are provided
407369
// through a specific CI runner).
408370
.env("LLVM_COMPONENTS", &self.config.llvm_components);

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

src/tools/run-make-support/src/external_deps/rustdoc.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,9 @@ use std::path::Path;
33

44
use crate::command::Command;
55
use crate::env::{env_var, env_var_os};
6-
use crate::util::set_host_rpath;
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

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
}

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
}

0 commit comments

Comments
 (0)