Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3253,6 +3253,7 @@ fn prepare_cargo_test(
builder: &Builder<'_>,
) -> BootstrapCommand {
let compiler = cargo.compiler();
let mode = cargo.mode();
let mut cargo: BootstrapCommand = cargo.into();

// Propagate `--bless` if it has not already been set/unset
Expand Down Expand Up @@ -3300,6 +3301,11 @@ fn prepare_cargo_test(
if builder.kind != Kind::Miri {
let mut dylib_paths = builder.rustc_lib_paths(compiler);
dylib_paths.push(builder.sysroot_target_libdir(compiler, target));
if mode == Mode::Rustc {
dylib_paths.extend(tool::discover_out_dirs_with_dylibs(
builder.cargo_out(compiler, Mode::Rustc, target).join("build"),
));
}
helpers::add_dylib_path(dylib_paths, &mut cargo);
}

Expand Down Expand Up @@ -3373,6 +3379,17 @@ impl Step for Crate {
builder.ensure(Std::new(build_compiler, build_compiler.host).force_recompile(true));
let record_failed_tests = builder.ensure(SetupFailedTestsFile);

let new_cargo = || {
builder::Cargo::new(
builder,
build_compiler,
mode,
SourceType::InTree,
target,
builder.kind,
)
};

let mut cargo = if builder.kind == Kind::Miri {
if builder.top_stage == 0 {
eprintln!("ERROR: `x.py miri` requires stage 1 or higher");
Expand Down Expand Up @@ -3425,14 +3442,7 @@ impl Step for Crate {
}

// Build `cargo test` command
builder::Cargo::new(
builder,
build_compiler,
mode,
SourceType::InTree,
target,
builder.kind,
)
new_cargo()
};

match mode {
Expand All @@ -3456,6 +3466,21 @@ impl Step for Crate {
_ => panic!("can only test libraries"),
};

if mode == Mode::Rustc {
// Build the test binaries before preparing the command that runs them. Some rustc
// dylibs are emitted into Cargo's build directory, and the run command needs to add
// those freshly-created directories to the dynamic library lookup path.

@bjorn3 bjorn3 Jun 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why cargo doesn't already add those dylibs. It should in principle do so for all dylibs that are dependencies of an executable. Or maybe that logic is broken in cargo with the new build dir layout?

View changes since the review

let mut build_only = new_cargo();
compile::rustc_cargo(builder, &mut build_only, target, &build_compiler, &self.crates);
build_only.arg("--no-run");
for krate in &self.crates {
build_only.arg("-p").arg(krate);
}

let mut build_only: BootstrapCommand = build_only.into();
build_only.run(builder);
}

let mut crates = self.crates.clone();
// The core and alloc crates can't directly be tested. We
// could silently ignore them, but adding their own test
Expand Down
5 changes: 3 additions & 2 deletions src/bootstrap/src/core/build_steps/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1660,8 +1660,9 @@ impl Builder<'_> {
}
}

/// Gets all of the `out` dirs in a given Cargo `build-dir/<profile>/build` dir.
fn discover_out_dirs_with_dylibs(dir: PathBuf) -> Vec<PathBuf> {
/// Gets all of the `out` dirs containing dylibs in a given Cargo
/// `build-dir/<profile>/build` dir.
pub(super) fn discover_out_dirs_with_dylibs(dir: PathBuf) -> Vec<PathBuf> {
if !dir.exists() {
return Vec::new();
}
Expand Down
Loading