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
11 changes: 11 additions & 0 deletions src/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! [`BuildContext`] is a (mostly) static information about a build task.

use std::path::PathBuf;

use crate::compiler::BuildConfig;
use crate::compiler::CompileKind;
use crate::compiler::Unit;
Expand Down Expand Up @@ -162,6 +164,15 @@ impl<'a, 'gctx> BuildContext<'a, 'gctx> {
pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
self.extra_compiler_args.get(unit)
}

/// Gets the path to the sysroot.
///
/// Helper function that uses GlobalContext.
pub fn get_sysroot(&self) -> PathBuf {
self.gctx
.get_sysroot(Some(self.ws))
.expect("able to invoke rustc")
}
}

#[derive(Copy, Clone, Default, Debug)]
Expand Down
3 changes: 0 additions & 3 deletions src/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ pub struct TargetInfo {
pub supports_std: Option<bool>,
/// Supported values for `-Csplit-debuginfo=` flag, queried from rustc
support_split_debuginfo: Vec<String>,
/// Path to the sysroot.
pub sysroot: PathBuf,
Comment on lines -56 to -57

@epage epage Jul 30, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We aren't saving this off but we are still looking it up in new to derive sysroot_target_libdir.

Should we remove the lookup here?

View changes since the review

/// Path to the "lib" directory in the sysroot which rustc uses for linking
/// target libraries.
pub sysroot_target_libdir: PathBuf,
Expand Down Expand Up @@ -352,7 +350,6 @@ impl TargetInfo {
return Ok(TargetInfo {
crate_type_process,
crate_types: RefCell::new(map),
sysroot,
sysroot_target_libdir,
rustflags: rustflags.into(),
rustdocflags: extra_args(
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/build_runner/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ fn compute_metadata(
// SourceId for stdlib crates is an absolute path inside the sysroot.
// Pass the sysroot as workspace root so that we hash a relative path.
// This avoids the metadata hash changing depending on where the user installed rustc.
&bcx.target_data.get_info(unit.kind).unwrap().sysroot
&bcx.get_sysroot()
} else {
bcx.ws.root()
};
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1586,19 +1586,19 @@ pub(crate) fn trim_paths_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit)
[
package_remap(build_runner, unit),
build_dir_remap(build_runner),
sysroot_remap(build_runner, unit),
sysroot_remap(build_runner),
]
}

/// Path prefix remap rules for sysroot.
///
/// This remap logic aligns with rustc:
/// <https://github.com/rust-lang/rust/blob/c2ef3516/src/bootstrap/src/lib.rs#L1113-L1116>
fn sysroot_remap(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> OsString {
fn sysroot_remap(build_runner: &BuildRunner<'_, '_>) -> OsString {
let mut remap = OsString::new();
remap.push({
// See also `detect_sysroot_src_path()`.
let mut sysroot = build_runner.bcx.target_data.info(unit.kind).sysroot.clone();
let mut sysroot = build_runner.bcx.get_sysroot();
sysroot.push("lib");
sysroot.push("rustlib");
sysroot.push("src");
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/rustdoc.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Utilities for building with rustdoc.

use crate::compiler::BuildContext;
use crate::compiler::build_runner::BuildRunner;
use crate::compiler::unit::Unit;
use crate::compiler::{BuildContext, CompileKind};
use crate::sources::CRATES_IO_REGISTRY;
use crate::util::data_structures::HashMap;
use crate::util::data_structures::HashSet;
Expand Down Expand Up @@ -208,7 +208,7 @@ pub fn add_root_urls(
let std_url = match &map.std {
None | Some(RustdocExternMode::Remote) => None,
Some(RustdocExternMode::Local) => {
let sysroot = &build_runner.bcx.target_data.info(CompileKind::Host).sysroot;
let sysroot = build_runner.bcx.get_sysroot();
let html_root = sysroot.join("share").join("doc").join("rust").join("html");
if html_root.exists() {
let url = Url::from_file_path(&html_root).map_err(|()| {
Expand Down
15 changes: 8 additions & 7 deletions src/compiler/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub fn resolve_std<'gctx>(
crates: &[String],
kinds: &[CompileKind],
) -> CargoResult<(PackageSet<'gctx>, Resolve, ResolvedFeatures)> {
let src_path = detect_sysroot_src_path(target_data)?;
let src_path = detect_sysroot_src_path(ws)?;
let std_ws_manifest_path = src_path.join("Cargo.toml");
let gctx = ws.gctx();
// TODO: Consider doing something to enforce --locked? Or to prevent the
Expand Down Expand Up @@ -217,15 +217,16 @@ fn generate_roots(
Ok(())
}

fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult<PathBuf> {
if let Some(s) = target_data.gctx.get_env_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
fn detect_sysroot_src_path(ws: &Workspace<'_>) -> CargoResult<PathBuf> {
if let Some(s) = ws.gctx().get_env_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
return Ok(s.into());
}

// NOTE: This is temporary until we figure out how to acquire the source.
let src_path = target_data
.info(CompileKind::Host)
.sysroot
let src_path = ws
.gctx()
.get_sysroot(Some(ws))
.expect("able to invoke rustc")
.join("lib")
.join("rustlib")
.join("src")
Expand All @@ -238,7 +239,7 @@ fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult<Pat
library, try:\n rustup component add rust-src",
lock
);
match target_data.gctx.get_env("RUSTUP_TOOLCHAIN") {
match ws.gctx().get_env("RUSTUP_TOOLCHAIN") {
Ok(rustup_toolchain) => {
anyhow::bail!("{} --toolchain {}", msg, rustup_toolchain);
}
Expand Down
22 changes: 22 additions & 0 deletions src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ pub struct GlobalContext {
cargo_exe: OnceLock<PathBuf>,
/// The location of the rustdoc executable
rustdoc: OnceLock<PathBuf>,
/// The path to the sysroot
sysroot: OnceLock<PathBuf>,
/// Whether we are printing extra verbose messages
extra_verbose: bool,
/// `frozen` is the same as `locked`, but additionally will not access the
Expand Down Expand Up @@ -379,6 +381,7 @@ impl GlobalContext {
cli_config: None,
cargo_exe: Default::default(),
rustdoc: Default::default(),
sysroot: Default::default(),
extra_verbose: false,
frozen: false,
locked: false,
Expand Down Expand Up @@ -610,6 +613,25 @@ impl GlobalContext {
.map(AsRef::as_ref)
}

/// Get the sysroot path.
pub fn get_sysroot<'gctx>(&'gctx self, ws: Option<&Workspace<'gctx>>) -> CargoResult<PathBuf> {
if self.cache_rustc_info {
let cached = self.sysroot.try_borrow_with(|| {
let rustc = self.load_global_rustc(ws)?;
rustc.sysroot(self)
});
cached.map(|sysroot| {
let mut ret = PathBuf::new();
// clone_from avoids reallocation
ret.clone_from(sysroot);
ret
Comment on lines +624 to +627

@epage epage Jul 30, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This would be true if ret had existed before, but it doesn't.

View changes since the review

})
} else {
let rustc = self.load_global_rustc(ws)?;
rustc.sysroot(self)
}
}

/// Which package sources have been updated, used to ensure it is only done once.
pub fn updated_sources(&self) -> MutexGuard<'_, HashSet<SourceId>> {
self.updated_sources.lock().unwrap()
Expand Down
5 changes: 3 additions & 2 deletions src/ops/cargo_fix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ use semver::Version;
use tracing::{debug, trace, warn};

pub use self::fix_edition::fix_edition;
use crate::compiler::CompileKind;
use crate::compiler::RustcTargetData;
use crate::ops::resolve::WorkspaceResolve;
use crate::ops::{self, CompileOptions};
Expand Down Expand Up @@ -185,7 +184,9 @@ pub fn fix(
wrapper.env(IDIOMS_ENV_INTERNAL, "1");
}

let sysroot = &target_data.info(CompileKind::Host).sysroot;
let sysroot = gctx
.get_sysroot(Some(original_ws))
.expect("able to invoke rustc");
if sysroot.is_dir() {
wrapper.env(SYSROOT_INTERNAL, sysroot);
}
Expand Down
12 changes: 12 additions & 0 deletions src/util/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl Rustc {
.wrapped(wrapper.as_deref());
apply_env_config(gctx, &mut cmd)?;
cmd.env(crate::CARGO_ENV, gctx.cargo_exe()?);

cmd.arg("-vV");
let verbose_version = cache.cached_output(&cmd, 0)?.0;

Expand Down Expand Up @@ -159,6 +160,17 @@ impl Rustc {
.unwrap()
.cached_output(cmd, extra_fingerprint)
}

/// Use the rustc executable to fetch the sysroot path.
pub fn sysroot(&self, gctx: &GlobalContext) -> CargoResult<PathBuf> {

@epage epage Jul 30, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this supposed to be in the previous commit?

View changes since the review

let mut cmd = self.workspace_process();
apply_env_config(gctx, &mut cmd)?;
cmd.env(crate::CARGO_ENV, gctx.cargo_exe()?);
cmd.arg("--print=sysroot");

let (stdout, _) = self.cached_output(&cmd, 0)?;
Ok(stdout.trim().into())
}
}

/// It is a well known fact that `rustc` is not the fastest compiler in the
Expand Down