Skip to content

rustc_session: Add a structure for keeping both explicit and default sysroots #142799

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
2 changes: 0 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3656,7 +3656,6 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"smallvec",
"tracing",
"unic-langid",
]
Expand Down Expand Up @@ -4447,7 +4446,6 @@ dependencies = [
"rustc_serialize",
"rustc_span",
"rustc_target",
"smallvec",
"termize",
"tracing",
"windows",
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ fn link_natively(
command: cmd,
escaped_output,
verbose: sess.opts.verbose,
sysroot_dir: sess.sysroot.clone(),
sysroot_dir: sess.opts.sysroot.path().to_owned(),
};
sess.dcx().emit_err(err);
// If MSVC's `link.exe` was expected but the return code
Expand Down Expand Up @@ -1249,10 +1249,10 @@ fn link_sanitizer_runtime(
if path.exists() {
sess.target_tlib_path.dir.clone()
} else {
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
filesearch::make_target_lib_path(
&sess.opts.sysroot.default,
sess.opts.target_triple.tuple(),
)
}
}

Expand Down Expand Up @@ -1758,7 +1758,7 @@ fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool {
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let full_path = dir.join(&linker_with_extension);
// If linker comes from sysroot assume self-contained mode
if full_path.is_file() && !full_path.starts_with(&sess.sysroot) {
if full_path.is_file() && !full_path.starts_with(sess.opts.sysroot.path()) {
return false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ impl<'a> Linker for MsvcLinker<'a> {
self.link_arg("/PDBALTPATH:%_PDB%");

// This will cause the Microsoft linker to embed .natvis info into the PDB file
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
let natvis_dir_path = self.sess.opts.sysroot.path().join("lib\\rustlib\\etc");
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
for entry in natvis_dir {
match entry {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ use rustc_metadata::locator;
use rustc_middle::ty::TyCtxt;
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_session::config::{
CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType,
CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, Sysroot,
UnstableOptions, Z_OPTIONS, nightly_options, parse_target_triple,
};
use rustc_session::getopts::{self, Matches};
use rustc_session::lint::{Lint, LintId};
use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target};
use rustc_session::{EarlyDiagCtxt, Session, config, filesearch};
use rustc_session::{EarlyDiagCtxt, Session, config};
use rustc_span::FileName;
use rustc_span::def_id::LOCAL_CRATE;
use rustc_target::json::ToJson;
Expand Down Expand Up @@ -657,7 +657,7 @@ fn print_crate_info(
println_info!("{}", targets.join("\n"));
}
HostTuple => println_info!("{}", rustc_session::config::host_tuple()),
Sysroot => println_info!("{}", sess.sysroot.display()),
Sysroot => println_info!("{}", sess.opts.sysroot.path().display()),
TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
TargetSpecJson => {
println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
Expand Down Expand Up @@ -1109,8 +1109,8 @@ fn get_backend_from_raw_matches(
let debug_flags = matches.opt_strs("Z");
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
let target = parse_target_triple(early_dcx, matches);
let sysroot = filesearch::materialize_sysroot(matches.opt_str("sysroot").map(PathBuf::from));
let target = config::build_target_config(early_dcx, &target, &sysroot);
let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
let target = config::build_target_config(early_dcx, &target, sysroot.path());

get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_error_messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
unic-langid = { version = "0.9.0", features = ["macros"] }
# tidy-alphabetical-end
11 changes: 6 additions & 5 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(anonymous_lifetime_in_impl_trait)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(type_alias_impl_trait)]
// tidy-alphabetical-end

use std::borrow::Cow;
use std::error::Error;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::sync::{Arc, LazyLock};
use std::{fmt, fs, io};

Expand All @@ -21,7 +22,6 @@ use intl_memoizer::concurrent::IntlLangMemoizer;
use rustc_data_structures::sync::IntoDynSyncSend;
use rustc_macros::{Decodable, Encodable};
use rustc_span::Span;
use smallvec::SmallVec;
use tracing::{instrument, trace};
pub use unic_langid::{LanguageIdentifier, langid};

Expand Down Expand Up @@ -105,9 +105,9 @@ impl From<Vec<FluentError>> for TranslationBundleError {
///
/// If `-Z additional-ftl-path` was provided, load that resource and add it to the bundle
/// (overriding any conflicting messages).
#[instrument(level = "trace")]
#[instrument(level = "trace", skip(sysroot_candidates))]
pub fn fluent_bundle(
sysroot_candidates: SmallVec<[PathBuf; 2]>,
sysroot_candidates: impl Iterator<Item = &Path>,
requested_locale: Option<LanguageIdentifier>,
additional_ftl_path: Option<&Path>,
with_directionality_markers: bool,
Expand Down Expand Up @@ -141,7 +141,8 @@ 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 mut sysroot in sysroot_candidates {
for sysroot in sysroot_candidates {
let mut sysroot = sysroot.to_owned();
sysroot.push("share");
sysroot.push("locale");
sysroot.push(requested_locale.to_string());
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ 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::sysroot_with_fallback;
use rustc_session::parse::ParseSess;
use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint};
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
Expand Down Expand Up @@ -407,8 +406,11 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se

crate::callbacks::setup_callbacks();

let sysroot = config.opts.sysroot.clone();
let target = config::build_target_config(&early_dcx, &config.opts.target_triple, &sysroot);
let target = config::build_target_config(
&early_dcx,
&config.opts.target_triple,
config.opts.sysroot.path(),
);
let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
let path_mapping = config.opts.file_path_mapping();
let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target);
Expand All @@ -428,7 +430,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
let codegen_backend = match config.make_codegen_backend {
None => util::get_codegen_backend(
&early_dcx,
&sysroot,
&config.opts.sysroot,
config.opts.unstable_opts.codegen_backend.as_deref(),
&target,
),
Expand All @@ -442,7 +444,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(
sysroot_with_fallback(&config.opts.sysroot),
config.opts.sysroot.all_paths(),
config.opts.unstable_opts.translate_lang.clone(),
config.opts.unstable_opts.translate_additional_ftl.as_deref(),
config.opts.unstable_opts.translate_directionality_markers,
Expand Down Expand Up @@ -471,7 +473,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
locale_resources,
config.lint_caps,
target,
sysroot,
util::rustc_version_str().unwrap_or("unknown"),
config.ice_file,
config.using_internal_features,
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ where

let matches = optgroups().parse(args).unwrap();
let sessopts = build_session_options(&mut early_dcx, &matches);
let sysroot = sessopts.sysroot.clone();
let target =
rustc_session::config::build_target_config(&early_dcx, &sessopts.target_triple, &sysroot);
let target = rustc_session::config::build_target_config(
&early_dcx,
&sessopts.target_triple,
sessopts.sysroot.path(),
);
let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target);
let checksum_hash_kind = sessopts.unstable_opts.checksum_hash_algorithm();
let sm_inputs = Some(SourceMapInputs {
Expand Down Expand Up @@ -72,7 +74,6 @@ where
vec![],
Default::default(),
target,
sysroot,
"",
None,
&USING_INTERNAL_FEATURES,
Expand Down
36 changes: 17 additions & 19 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_data_structures::sync;
use rustc_metadata::{DylibError, load_symbol_from_dylib};
use rustc_middle::ty::CurrentGcx;
use rustc_parse::validate_attr;
use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_tuple};
use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
use rustc_session::{EarlyDiagCtxt, Session, filesearch};
Expand Down Expand Up @@ -305,7 +305,7 @@ fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBacken
/// A name of `None` indicates that the default backend should be used.
pub fn get_codegen_backend(
early_dcx: &EarlyDiagCtxt,
sysroot: &Path,
sysroot: &Sysroot,
backend_name: Option<&str>,
target: &Target,
) -> Box<dyn CodegenBackend> {
Expand Down Expand Up @@ -336,25 +336,24 @@ pub fn get_codegen_backend(
// This is used for rustdoc, but it uses similar machinery to codegen backend
// loading, so we leave the code here. It is potentially useful for other tools
// that want to invoke the rustc binary while linking to rustc as well.
pub fn rustc_path<'a>() -> Option<&'a Path> {
pub fn rustc_path<'a>(sysroot: &Sysroot) -> Option<&'a Path> {
static RUSTC_PATH: OnceLock<Option<PathBuf>> = OnceLock::new();

const BIN_PATH: &str = env!("RUSTC_INSTALL_BINDIR");

RUSTC_PATH.get_or_init(|| get_rustc_path_inner(BIN_PATH)).as_deref()
}

fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
let candidate = filesearch::get_or_default_sysroot()
.join(bin_path)
.join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" });
candidate.exists().then_some(candidate)
RUSTC_PATH
.get_or_init(|| {
let candidate = sysroot
.default
.join(env!("RUSTC_INSTALL_BINDIR"))
.join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" });
candidate.exists().then_some(candidate)
})
.as_deref()
}

#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn get_codegen_sysroot(
early_dcx: &EarlyDiagCtxt,
sysroot: &Path,
sysroot: &Sysroot,
backend_name: &str,
) -> MakeBackendFn {
// For now we only allow this function to be called once as it'll dlopen a
Expand All @@ -369,10 +368,9 @@ fn get_codegen_sysroot(
);

let target = host_tuple();
let sysroot_candidates = filesearch::sysroot_with_fallback(&sysroot);

let sysroot = sysroot_candidates
.iter()
let sysroot = sysroot
.all_paths()
.map(|sysroot| {
filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends")
})
Expand All @@ -381,8 +379,8 @@ fn get_codegen_sysroot(
f.exists()
})
.unwrap_or_else(|| {
let candidates = sysroot_candidates
.iter()
let candidates = sysroot
.all_paths()
.map(|p| p.display().to_string())
.collect::<Vec<_>>()
.join("\n* ");
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl<'a> CrateLocator<'a> {

CrateLocator {
only_needs_metadata,
sysroot: &sess.sysroot,
sysroot: sess.opts.sysroot.path(),
metadata_loader,
cfg_version: sess.cfg_version,
crate_name,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_session/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
smallvec = "1.8.1"
termize = "0.1.1"
tracing = "0.1"
# tidy-alphabetical-end
Expand Down
31 changes: 26 additions & 5 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,28 @@ bitflags::bitflags! {
}
}

#[derive(Clone, Debug)]
pub struct Sysroot {
pub explicit: Option<PathBuf>,
pub default: PathBuf,
}

impl Sysroot {
pub fn new(explicit: Option<PathBuf>) -> Sysroot {
Sysroot { explicit, default: filesearch::default_sysroot() }
}

/// Return explicit sysroot if it was passed with `--sysroot`, or default sysroot otherwise.
pub fn path(&self) -> &Path {
self.explicit.as_deref().unwrap_or(&self.default)
}

/// Returns both explicit sysroot if it was passed with `--sysroot` and the default sysroot.
pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
}
}

pub fn host_tuple() -> &'static str {
// Get the host triple out of the build environment. This ensures that our
// idea of the host triple is the same as for the set of libraries we've
Expand Down Expand Up @@ -1342,7 +1364,7 @@ impl Default for Options {
describe_lints: false,
output_types: OutputTypes(BTreeMap::new()),
search_paths: vec![],
sysroot: filesearch::materialize_sysroot(None),
sysroot: Sysroot::new(None),
target_triple: TargetTuple::from_tuple(host_tuple()),
test: false,
incremental: None,
Expand Down Expand Up @@ -2673,7 +2695,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M

let cg = cg;

let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let target_triple = parse_target_triple(early_dcx, matches);
let opt_level = parse_opt_level(early_dcx, matches, &cg);
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
Expand Down Expand Up @@ -2712,10 +2733,10 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M

let logical_env = parse_logical_env(early_dcx, matches);

let sysroot = filesearch::materialize_sysroot(sysroot_opt);
let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));

let real_source_base_dir = |suffix: &str, confirm: &str| {
let mut candidate = sysroot.join(suffix);
let mut candidate = sysroot.path().join(suffix);
if let Ok(metadata) = candidate.symlink_metadata() {
// Replace the symlink bootstrap creates, with its destination.
// We could try to use `fs::canonicalize` instead, but that might
Expand All @@ -2742,7 +2763,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let mut search_paths = vec![];
for s in &matches.opt_strs("L") {
search_paths.push(SearchPath::from_cli_opt(
&sysroot,
sysroot.path(),
&target_triple,
early_dcx,
s,
Expand Down
Loading
Loading