Skip to content

Commit 856542e

Browse files
authored
Rustc: Simplify --sysroot code after rust#103660 (#325)
1 parent e1dfde8 commit 856542e

File tree

1 file changed

+30
-73
lines changed

1 file changed

+30
-73
lines changed

marker_rustc_driver/src/lib.rs

Lines changed: 30 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ pub mod lint_pass;
3737

3838
use std::env;
3939
use std::ops::Deref;
40-
use std::process::Command;
4140

42-
use camino::{Utf8Path, Utf8PathBuf};
41+
use camino::Utf8Path;
4342
use marker_adapter::{LintCrateInfo, LINT_CRATES_ENV};
4443
use marker_error::Context;
4544

@@ -49,8 +48,10 @@ use crate::conversion::rustc::RustcConverter;
4948
const RUSTC_TOOLCHAIN_VERSION: &str = "nightly-2023-11-16";
5049
// endregion replace rust toolchain dev
5150

51+
pub const MARKER_SYSROOT_ENV: &str = "MARKER_SYSROOT";
52+
5253
struct DefaultCallbacks {
53-
env_vars: Vec<(&'static str, String)>,
54+
env_vars: Vec<&'static str>,
5455
}
5556
impl rustc_driver::Callbacks for DefaultCallbacks {
5657
fn config(&mut self, config: &mut rustc_interface::Config) {
@@ -62,7 +63,7 @@ impl rustc_driver::Callbacks for DefaultCallbacks {
6263
}
6364

6465
struct MarkerCallback {
65-
env_vars: Vec<(&'static str, String)>,
66+
env_vars: Vec<&'static str>,
6667
lint_crates: Vec<LintCrateInfo>,
6768
}
6869

@@ -105,12 +106,15 @@ impl rustc_driver::Callbacks for MarkerCallback {
105106
}
106107
}
107108

108-
fn register_tracked_env(sess: &mut rustc_session::parse::ParseSess, vars: &[(&'static str, String)]) {
109+
fn register_tracked_env(sess: &mut rustc_session::parse::ParseSess, vars: &[&'static str]) {
109110
use rustc_span::Symbol;
110111
let env = sess.env_depinfo.get_mut();
111112

112-
for (key, value) in vars {
113-
env.insert((Symbol::intern(key), Some(Symbol::intern(value))));
113+
for key in vars {
114+
env.insert((
115+
Symbol::intern(key),
116+
Some(Symbol::intern(&std::env::var(key).unwrap_or_default())),
117+
));
114118
}
115119
}
116120

@@ -167,17 +171,6 @@ fn arg_value<'a, T: Deref<Target = str>>(
167171
None
168172
}
169173

170-
fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<Utf8PathBuf> {
171-
home.and_then(|home| {
172-
toolchain.map(|toolchain| {
173-
let mut path = Utf8PathBuf::from(home);
174-
path.push("toolchains");
175-
path.push(toolchain);
176-
path
177-
})
178-
})
179-
}
180-
181174
fn display_help() {
182175
println!(
183176
"\
@@ -208,15 +201,24 @@ pub fn try_main(args: impl Iterator<Item = String>) -> Result<(), MainError> {
208201
// values. These are usually driver-independent and handled by the adapter.
209202
let mut orig_args: Vec<String> = args.collect();
210203

211-
let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
212-
let has_sys_root_arg = sys_root_arg.is_some();
213-
214-
// Further invocation of rustc require the `--sysroot` flag. We add it here
215-
// in preparation.
216-
if !has_sys_root_arg {
217-
let sys_root = find_sys_root(sys_root_arg);
218-
orig_args.extend(["--sysroot".into(), sys_root]);
219-
};
204+
// Rustc will by default use the location of the rustc library as the system
205+
// root. Custom drivers, like Clippy, rustdoc, and Miri have options to override
206+
// this directory. This seems to be required for cross compiling and cases where
207+
// the driver is invoked directly.
208+
//
209+
// I haven't found a definite explanation which circumstances require it, but
210+
// it's probably best to support the same behavior. This code is an adaptation
211+
// of Clippy's solution, with the deviation, that we add the `--sysroot` directly
212+
// and have a `MARKER_` prefix for the `SYSROOT` environment value. This is similar
213+
// to Miri's `MIRI_SYSROOT` variable.
214+
//
215+
// The `ui_test` crate used by `marker_uitest` seems to also fiddle around with
216+
// the system root, if custom dependencies are defined.
217+
if arg_value(&orig_args, "--sysroot", |_| true).is_none()
218+
&& let Ok(env_sys_root) = std::env::var(MARKER_SYSROOT_ENV)
219+
{
220+
orig_args.extend(vec!["--sysroot".into(), env_sys_root]);
221+
}
220222

221223
// make "marker_rustc_driver --rustc" work like a subcommand that passes
222224
// all args to "rustc" for example `marker_rustc_driver --rustc --version`
@@ -270,7 +272,7 @@ pub fn try_main(args: impl Iterator<Item = String>) -> Result<(), MainError> {
270272
let in_primary_package = env::var("CARGO_PRIMARY_PACKAGE").is_ok();
271273

272274
let enable_marker = !cap_lints_allow && (!no_deps || in_primary_package);
273-
let env_vars = vec![(LINT_CRATES_ENV, std::env::var(LINT_CRATES_ENV).unwrap_or_default())];
275+
let env_vars = vec![LINT_CRATES_ENV, MARKER_SYSROOT_ENV];
274276
if !enable_marker {
275277
rustc_driver::RunCompiler::new(&orig_args, &mut DefaultCallbacks { env_vars }).run()?;
276278
return Ok(());
@@ -306,51 +308,6 @@ pub fn try_main(args: impl Iterator<Item = String>) -> Result<(), MainError> {
306308
Ok(())
307309
}
308310

309-
/// Get the sysroot, looking from most specific to this invocation to the least:
310-
/// - command line
311-
/// - runtime environment
312-
/// - `SYSROOT`
313-
/// - `RUSTUP_HOME`, `MULTIRUST_HOME`, `RUSTUP_TOOLCHAIN`, `MULTIRUST_TOOLCHAIN`
314-
/// - sysroot from rustc in the path
315-
/// - compile-time environment
316-
/// - `SYSROOT`
317-
/// - `RUSTUP_HOME`, `MULTIRUST_HOME`, `RUSTUP_TOOLCHAIN`, `MULTIRUST_TOOLCHAIN`
318-
fn find_sys_root(sys_root_arg: Option<&str>) -> String {
319-
sys_root_arg
320-
.map(Utf8PathBuf::from)
321-
.or_else(|| std::env::var("SYSROOT").ok().map(Utf8PathBuf::from))
322-
.or_else(|| {
323-
let home = std::env::var("RUSTUP_HOME")
324-
.or_else(|_| std::env::var("MULTIRUST_HOME"))
325-
.ok();
326-
let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
327-
.or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
328-
.ok();
329-
toolchain_path(home, toolchain)
330-
})
331-
.or_else(|| {
332-
Command::new("rustc")
333-
.arg("--print")
334-
.arg("sysroot")
335-
.output()
336-
.ok()
337-
.and_then(|out| String::from_utf8(out.stdout).ok())
338-
.map(|s| Utf8PathBuf::from(s.trim()))
339-
})
340-
.or_else(|| option_env!("SYSROOT").map(Utf8PathBuf::from))
341-
.or_else(|| {
342-
let home = option_env!("RUSTUP_HOME")
343-
.or(option_env!("MULTIRUST_HOME"))
344-
.map(ToString::to_string);
345-
let toolchain = option_env!("RUSTUP_TOOLCHAIN")
346-
.or(option_env!("MULTIRUST_TOOLCHAIN"))
347-
.map(ToString::to_string);
348-
toolchain_path(home, toolchain)
349-
})
350-
.map(Utf8PathBuf::into_string)
351-
.expect("need to specify SYSROOT env var during marker compilation, or use rustup or multirust")
352-
}
353-
354311
pub enum MainError {
355312
Custom(marker_error::Error),
356313
Rustc(rustc_span::ErrorGuaranteed),

0 commit comments

Comments
 (0)