Skip to content

Cleanup sysroot locating a bit #138404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 13, 2025
Merged
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
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1286,8 +1286,7 @@ fn link_sanitizer_runtime(
if path.exists() {
sess.target_tlib_path.dir.clone()
} else {
let default_sysroot =
filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
let default_sysroot = filesearch::get_or_default_sysroot();
let default_tlib =
filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.tuple());
default_tlib
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ impl From<Vec<FluentError>> for TranslationBundleError {
/// (overriding any conflicting messages).
#[instrument(level = "trace")]
pub fn fluent_bundle(
mut user_provided_sysroot: Option<PathBuf>,
mut sysroot_candidates: Vec<PathBuf>,
sysroot: PathBuf,
sysroot_candidates: Vec<PathBuf>,
requested_locale: Option<LanguageIdentifier>,
additional_ftl_path: Option<&Path>,
with_directionality_markers: bool,
Expand Down Expand Up @@ -142,7 +142,7 @@ pub fn fluent_bundle(
// If the user requests the default locale then don't try to load anything.
if let Some(requested_locale) = requested_locale {
let mut found_resources = false;
for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) {
for mut sysroot in Some(sysroot).into_iter().chain(sysroot_candidates.into_iter()) {
sysroot.push("share");
sysroot.push("locale");
sysroot.push(requested_locale.to_string());
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe;
use rustc_query_impl::QueryCtxt;
use rustc_query_system::query::print_query_stack;
use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
use rustc_session::filesearch::{self, sysroot_candidates};
use rustc_session::filesearch::sysroot_candidates;
use rustc_session::parse::ParseSess;
use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint};
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
Expand Down Expand Up @@ -390,7 +390,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se

crate::callbacks::setup_callbacks();

let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
let sysroot = config.opts.sysroot.clone();
let target = config::build_target_config(&early_dcx, &config.opts.target_triple, &sysroot);
let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
let path_mapping = config.opts.file_path_mapping();
Expand Down Expand Up @@ -424,7 +424,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);

let bundle = match rustc_errors::fluent_bundle(
config.opts.maybe_sysroot.clone(),
config.opts.sysroot.clone(),
sysroot_candidates().to_vec(),
config.opts.unstable_opts.translate_lang.clone(),
config.opts.unstable_opts.translate_additional_ftl.as_deref(),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_session::config::{
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, filesearch, getopts};
use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, getopts};
use rustc_span::edition::{DEFAULT_EDITION, Edition};
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
use rustc_span::{FileName, SourceFileHashAlgorithm, sym};
Expand All @@ -41,7 +41,7 @@ where

let matches = optgroups().parse(args).unwrap();
let sessopts = build_session_options(&mut early_dcx, &matches);
let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());
let sysroot = sessopts.sysroot.clone();
let target =
rustc_session::config::build_target_config(&early_dcx, &sessopts.target_triple, &sysroot);
let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ impl Default for Options {
describe_lints: false,
output_types: OutputTypes(BTreeMap::new()),
search_paths: vec![],
maybe_sysroot: None,
sysroot: filesearch::materialize_sysroot(None),
Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe this should use PathBuf::new()? It is only used for tests.

target_triple: TargetTuple::from_tuple(host_tuple()),
test: false,
incremental: None,
Expand Down Expand Up @@ -2618,7 +2618,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
describe_lints,
output_types,
search_paths,
maybe_sysroot: Some(sysroot),
sysroot,
target_triple,
test,
incremental,
Expand Down
48 changes: 21 additions & 27 deletions compiler/rustc_session/src/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ fn current_dll_path() -> Result<PathBuf, String> {

pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
let target = crate::config::host_tuple();
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()];
let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
if let Ok(dll) = path {
// use `parent` twice to chop off the file name and then also the
Expand Down Expand Up @@ -195,12 +194,12 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
/// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none.
/// Panics if [`get_or_default_sysroot`] returns an error.
pub fn materialize_sysroot(maybe_sysroot: Option<PathBuf>) -> PathBuf {
maybe_sysroot.unwrap_or_else(|| get_or_default_sysroot().expect("Failed finding sysroot"))
maybe_sysroot.unwrap_or_else(|| get_or_default_sysroot())
}

/// This function checks if sysroot is found using env::args().next(), and if it
/// is not found, finds sysroot from current rustc_driver dll.
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
pub fn get_or_default_sysroot() -> PathBuf {
// Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: PathBuf) -> PathBuf {
let path = try_canonicalize(&path).unwrap_or(path);
Expand Down Expand Up @@ -255,30 +254,25 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
// binary able to locate Rust libraries in systems using content-addressable
// storage (CAS).
fn from_env_args_next() -> Option<PathBuf> {
match env::args_os().next() {
Some(first_arg) => {
let mut p = PathBuf::from(first_arg);

// Check if sysroot is found using env::args().next() only if the rustc in argv[0]
// is a symlink (see #79253). We might want to change/remove it to conform with
// https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the
// future.
if fs::read_link(&p).is_err() {
// Path is not a symbolic link or does not exist.
return None;
}

// Pop off `bin/rustc`, obtaining the suspected sysroot.
p.pop();
p.pop();
// Look for the target rustlib directory in the suspected sysroot.
let mut rustlib_path = rustc_target::relative_target_rustlib_path(&p, "dummy");
rustlib_path.pop(); // pop off the dummy target.
rustlib_path.exists().then_some(p)
}
None => None,
let mut p = PathBuf::from(env::args_os().next()?);

// Check if sysroot is found using env::args().next() only if the rustc in argv[0]
// is a symlink (see #79253). We might want to change/remove it to conform with
// https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the
// future.
if fs::read_link(&p).is_err() {
// Path is not a symbolic link or does not exist.
return None;
}

// Pop off `bin/rustc`, obtaining the suspected sysroot.
p.pop();
p.pop();
// Look for the target rustlib directory in the suspected sysroot.
let mut rustlib_path = rustc_target::relative_target_rustlib_path(&p, "dummy");
rustlib_path.pop(); // pop off the dummy target.
rustlib_path.exists().then_some(p)
}

Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?))
from_env_args_next().unwrap_or(default_from_rustc_driver_dll().expect("Failed finding sysroot"))
}
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ top_level_options!(
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
libs: Vec<NativeLib> [TRACKED],
maybe_sysroot: Option<PathBuf> [UNTRACKED],
sysroot: PathBuf [UNTRACKED],

target_triple: TargetTuple [TRACKED],

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ pub struct Session {
pub target: Target,
pub host: Target,
pub opts: config::Options,
pub host_tlib_path: Arc<SearchPath>,
pub target_tlib_path: Arc<SearchPath>,
pub psess: ParseSess,
pub sysroot: PathBuf,
Expand Down Expand Up @@ -1042,6 +1041,7 @@ pub fn build_session(

let host_triple = config::host_tuple();
let target_triple = sopts.target_triple.tuple();
// FIXME use host sysroot?
let host_tlib_path = Arc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple));
let target_tlib_path = if host_triple == target_triple {
// Use the same `SearchPath` if host and target triple are identical to avoid unnecessary
Expand Down Expand Up @@ -1070,7 +1070,6 @@ pub fn build_session(
target,
host,
opts: sopts,
host_tlib_path,
target_tlib_path,
psess,
sysroot,
Expand Down
11 changes: 5 additions & 6 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ pub(crate) struct Options {
/// compiling doctests from the crate.
pub(crate) edition: Edition,
/// The path to the sysroot. Used during the compilation process.
pub(crate) sysroot: PathBuf,
/// Has the same value as `sysroot` except is `None` when the user didn't pass `---sysroot`.
pub(crate) maybe_sysroot: Option<PathBuf>,
/// Lint information passed over the command-line.
pub(crate) lint_opts: Vec<(String, Level)>,
Expand Down Expand Up @@ -202,6 +204,7 @@ impl fmt::Debug for Options {
.field("unstable_options", &"...")
.field("target", &self.target)
.field("edition", &self.edition)
.field("sysroot", &self.sysroot)
.field("maybe_sysroot", &self.maybe_sysroot)
.field("lint_opts", &self.lint_opts)
.field("describe_lints", &self.describe_lints)
Expand Down Expand Up @@ -729,12 +732,7 @@ impl Options {
let target = parse_target_triple(early_dcx, matches);
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);

let sysroot = match &maybe_sysroot {
Some(s) => s.clone(),
None => {
rustc_session::filesearch::get_or_default_sysroot().expect("Failed finding sysroot")
}
};
let sysroot = rustc_session::filesearch::materialize_sysroot(maybe_sysroot.clone());

let libs = matches
.opt_strs("L")
Expand Down Expand Up @@ -834,6 +832,7 @@ impl Options {
unstable_opts_strs,
target,
edition,
sysroot,
maybe_sysroot,
lint_opts,
describe_lints,
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pub(crate) fn create_config(
unstable_opts,
target,
edition,
maybe_sysroot,
sysroot,
lint_opts,
describe_lints,
lint_cap,
Expand Down Expand Up @@ -253,7 +253,7 @@ pub(crate) fn create_config(
let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
// plays with error output here!
let sessopts = config::Options {
maybe_sysroot,
sysroot,
search_paths: libs,
crate_types,
lint_opts,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
if options.proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };

let sessopts = config::Options {
maybe_sysroot: options.maybe_sysroot.clone(),
sysroot: options.sysroot.clone(),
search_paths: options.libs.clone(),
crate_types,
lint_opts,
Expand Down
2 changes: 1 addition & 1 deletion tests/ui-fulldeps/run-compiler-twice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn main() {
fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path>) {
let mut opts = Options::default();
opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
opts.maybe_sysroot = Some(sysroot);
opts.sysroot = sysroot;

if let Some(linker) = linker {
opts.cg.linker = Some(linker.to_owned());
Expand Down
Loading