Prefer cargo proxies when setting RUSTUP_TOOLCHAIN

This commit is contained in:
Lukas Wirth 2024-03-05 10:44:17 +01:00
parent c310aee8d6
commit 6b48133e9a
7 changed files with 54 additions and 64 deletions

View file

@ -71,8 +71,7 @@ impl WorkspaceBuildScripts {
cmd cmd
} }
_ => { _ => {
let mut cmd = Command::new(Tool::Cargo.path()); let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]); cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
cmd.args(&config.extra_args); cmd.args(&config.extra_args);
@ -430,8 +429,7 @@ impl WorkspaceBuildScripts {
} }
let res = (|| { let res = (|| {
let target_libdir = (|| { let target_libdir = (|| {
let mut cargo_config = Command::new(Tool::Cargo.path()); let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
cargo_config.envs(extra_env); cargo_config.envs(extra_env);
cargo_config cargo_config
.current_dir(current_dir) .current_dir(current_dir)
@ -440,7 +438,7 @@ impl WorkspaceBuildScripts {
if let Ok(it) = utf8_stdout(cargo_config) { if let Ok(it) = utf8_stdout(cargo_config) {
return Ok(it); return Ok(it);
} }
let mut cmd = Sysroot::rustc(sysroot); let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
cmd.envs(extra_env); cmd.envs(extra_env);
cmd.args(["--print", "target-libdir"]); cmd.args(["--print", "target-libdir"]);
utf8_stdout(cmd) utf8_stdout(cmd)

View file

@ -1,8 +1,8 @@
//! See [`CargoWorkspace`]. //! See [`CargoWorkspace`].
use std::ops;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::from_utf8; use std::str::from_utf8;
use std::{ops, process::Command};
use anyhow::Context; use anyhow::Context;
use base_db::Edition; use base_db::Edition;
@ -243,8 +243,11 @@ impl CargoWorkspace {
) -> anyhow::Result<cargo_metadata::Metadata> { ) -> anyhow::Result<cargo_metadata::Metadata> {
let targets = find_list_of_build_targets(config, cargo_toml, sysroot); let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
let cargo = Sysroot::tool(sysroot, Tool::Cargo);
let mut meta = MetadataCommand::new(); let mut meta = MetadataCommand::new();
meta.cargo_path(Tool::Cargo.path()); meta.cargo_path(cargo.get_program());
cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default()));
config.extra_env.iter().for_each(|(var, val)| _ = meta.env(var, val));
meta.manifest_path(cargo_toml.to_path_buf()); meta.manifest_path(cargo_toml.to_path_buf());
match &config.features { match &config.features {
CargoFeatures::All => { CargoFeatures::All => {
@ -291,10 +294,7 @@ impl CargoWorkspace {
progress("metadata".to_owned()); progress("metadata".to_owned());
(|| -> Result<cargo_metadata::Metadata, cargo_metadata::Error> { (|| -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
let mut command = meta.cargo_command(); let output = meta.cargo_command().output()?;
Sysroot::set_rustup_toolchain_env(&mut command, sysroot);
command.envs(&config.extra_env);
let output = command.output()?;
if !output.status.success() { if !output.status.success() {
return Err(cargo_metadata::Error::CargoMetadata { return Err(cargo_metadata::Error::CargoMetadata {
stderr: String::from_utf8(output.stderr)?, stderr: String::from_utf8(output.stderr)?,
@ -501,7 +501,7 @@ fn rustc_discover_host_triple(
extra_env: &FxHashMap<String, String>, extra_env: &FxHashMap<String, String>,
sysroot: Option<&Sysroot>, sysroot: Option<&Sysroot>,
) -> Option<String> { ) -> Option<String> {
let mut rustc = Sysroot::rustc(sysroot); let mut rustc = Sysroot::tool(sysroot, Tool::Rustc);
rustc.envs(extra_env); rustc.envs(extra_env);
rustc.current_dir(cargo_toml.parent()).arg("-vV"); rustc.current_dir(cargo_toml.parent()).arg("-vV");
tracing::debug!("Discovering host platform by {:?}", rustc); tracing::debug!("Discovering host platform by {:?}", rustc);
@ -529,8 +529,7 @@ fn cargo_config_build_target(
extra_env: &FxHashMap<String, String>, extra_env: &FxHashMap<String, String>,
sysroot: Option<&Sysroot>, sysroot: Option<&Sysroot>,
) -> Vec<String> { ) -> Vec<String> {
let mut cargo_config = Command::new(Tool::Cargo.path()); let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
cargo_config.envs(extra_env); cargo_config.envs(extra_env);
cargo_config cargo_config
.current_dir(cargo_toml.parent()) .current_dir(cargo_toml.parent())

View file

@ -1,9 +1,8 @@
//! Runs `rustc --print cfg` to get built-in cfg flags. //! Runs `rustc --print cfg` to get built-in cfg flags.
use std::process::Command;
use anyhow::Context; use anyhow::Context;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use toolchain::Tool;
use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot}; use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
@ -69,8 +68,8 @@ fn get_rust_cfgs(
) -> anyhow::Result<String> { ) -> anyhow::Result<String> {
let sysroot = match config { let sysroot = match config {
RustcCfgConfig::Cargo(sysroot, cargo_toml) => { RustcCfgConfig::Cargo(sysroot, cargo_toml) => {
let mut cmd = Command::new(toolchain::Tool::Cargo.path()); let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env); cmd.envs(extra_env);
cmd.current_dir(cargo_toml.parent()) cmd.current_dir(cargo_toml.parent())
.args(["rustc", "-Z", "unstable-options", "--print", "cfg"]) .args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
@ -90,7 +89,7 @@ fn get_rust_cfgs(
RustcCfgConfig::Rustc(sysroot) => sysroot, RustcCfgConfig::Rustc(sysroot) => sysroot,
}; };
let mut cmd = Sysroot::rustc(sysroot); let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
cmd.envs(extra_env); cmd.envs(extra_env);
cmd.args(["--print", "cfg", "-O"]); cmd.args(["--print", "cfg", "-O"]);
if let Some(target) = target { if let Some(target) = target {

View file

@ -193,23 +193,26 @@ impl Sysroot {
Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata)) Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata))
} }
pub fn set_rustup_toolchain_env(cmd: &mut Command, sysroot: Option<&Self>) { /// Returns a command to run a tool preferring the cargo proxies if the sysroot exists.
if let Some(sysroot) = sysroot { pub fn tool(sysroot: Option<&Self>, tool: Tool) -> Command {
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root)); match sysroot {
}
}
/// Returns a `Command` that is configured to run `rustc` from the sysroot if it exists,
/// otherwise returns what [toolchain::Tool::Rustc] returns.
pub fn rustc(sysroot: Option<&Self>) -> Command {
let mut cmd = Command::new(match sysroot {
Some(sysroot) => { Some(sysroot) => {
toolchain::Tool::Rustc.path_in_or_discover(sysroot.root.join("bin").as_ref()) // special case rustc, we can look that up directly in the sysroot's bin folder
// as it should never invoke another cargo binary
if let Tool::Rustc = tool {
if let Some(path) =
probe_for_binary(sysroot.root.join("bin").join(Tool::Rustc.name()).into())
{
return Command::new(path);
}
}
let mut cmd = Command::new(tool.prefer_proxy());
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root));
cmd
} }
None => toolchain::Tool::Rustc.path(), _ => Command::new(tool.path()),
}); }
Self::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd
} }
pub fn discover_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> { pub fn discover_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> {

View file

@ -1,7 +1,7 @@
//! Runs `rustc --print target-spec-json` to get the target_data_layout. //! Runs `rustc --print target-spec-json` to get the target_data_layout.
use std::process::Command;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use toolchain::Tool;
use crate::{utf8_stdout, ManifestPath, Sysroot}; use crate::{utf8_stdout, ManifestPath, Sysroot};
@ -28,8 +28,7 @@ pub fn get(
}; };
let sysroot = match config { let sysroot = match config {
RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => { RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => {
let mut cmd = Command::new(toolchain::Tool::Cargo.path()); let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env); cmd.envs(extra_env);
cmd.current_dir(cargo_toml.parent()) cmd.current_dir(cargo_toml.parent())
.args([ .args([
@ -57,7 +56,7 @@ pub fn get(
RustcDataLayoutConfig::Rustc(sysroot) => sysroot, RustcDataLayoutConfig::Rustc(sysroot) => sysroot,
}; };
let mut cmd = Sysroot::rustc(sysroot); let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
cmd.envs(extra_env) cmd.envs(extra_env)
.args(["-Z", "unstable-options", "--print", "target-spec-json"]) .args(["-Z", "unstable-options", "--print", "target-spec-json"])
.env("RUSTC_BOOTSTRAP", "1"); .env("RUSTC_BOOTSTRAP", "1");

View file

@ -2,7 +2,7 @@
//! metadata` or `rust-project.json`) into representation stored in the salsa //! metadata` or `rust-project.json`) into representation stored in the salsa
//! database -- `CrateGraph`. //! database -- `CrateGraph`.
use std::{collections::VecDeque, fmt, fs, iter, process::Command, str::FromStr, sync}; use std::{collections::VecDeque, fmt, fs, iter, str::FromStr, sync};
use anyhow::{format_err, Context}; use anyhow::{format_err, Context};
use base_db::{ use base_db::{
@ -172,11 +172,13 @@ impl fmt::Debug for ProjectWorkspace {
fn get_toolchain_version( fn get_toolchain_version(
current_dir: &AbsPath, current_dir: &AbsPath,
mut cmd: Command, sysroot: Option<&Sysroot>,
tool: Tool,
extra_env: &FxHashMap<String, String>, extra_env: &FxHashMap<String, String>,
prefix: &str, prefix: &str,
) -> Result<Option<Version>, anyhow::Error> { ) -> Result<Option<Version>, anyhow::Error> {
let cargo_version = utf8_stdout({ let cargo_version = utf8_stdout({
let mut cmd = Sysroot::tool(sysroot, tool);
cmd.envs(extra_env); cmd.envs(extra_env);
cmd.arg("--version").current_dir(current_dir); cmd.arg("--version").current_dir(current_dir);
cmd cmd
@ -297,11 +299,8 @@ impl ProjectWorkspace {
let toolchain = get_toolchain_version( let toolchain = get_toolchain_version(
cargo_toml.parent(), cargo_toml.parent(),
{ sysroot_ref,
let mut cmd = Command::new(toolchain::Tool::Cargo.path()); Tool::Cargo,
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot_ref);
cmd
},
&config.extra_env, &config.extra_env,
"cargo ", "cargo ",
)?; )?;
@ -386,7 +385,8 @@ impl ProjectWorkspace {
let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref); let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref);
let toolchain = match get_toolchain_version( let toolchain = match get_toolchain_version(
project_json.path(), project_json.path(),
Sysroot::rustc(sysroot_ref), sysroot_ref,
Tool::Rustc,
extra_env, extra_env,
"rustc ", "rustc ",
) { ) {
@ -433,18 +433,15 @@ impl ProjectWorkspace {
}; };
let sysroot_ref = sysroot.as_ref().ok(); let sysroot_ref = sysroot.as_ref().ok();
let toolchain = match get_toolchain_version( let toolchain =
dir, match get_toolchain_version(dir, sysroot_ref, Tool::Rustc, &config.extra_env, "rustc ")
Sysroot::rustc(sysroot_ref), {
&config.extra_env, Ok(it) => it,
"rustc ", Err(e) => {
) { tracing::error!("{e}");
Ok(it) => it, None
Err(e) => { }
tracing::error!("{e}"); };
None
}
};
let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(sysroot_ref)); let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(sysroot_ref));
let data_layout = target_data_layout::get( let data_layout = target_data_layout::get(
@ -1573,8 +1570,7 @@ fn cargo_config_env(
extra_env: &FxHashMap<String, String>, extra_env: &FxHashMap<String, String>,
sysroot: Option<&Sysroot>, sysroot: Option<&Sysroot>,
) -> FxHashMap<String, String> { ) -> FxHashMap<String, String> {
let mut cargo_config = Command::new(Tool::Cargo.path()); let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
cargo_config.envs(extra_env); cargo_config.envs(extra_env);
cargo_config cargo_config
.current_dir(cargo_toml.parent()) .current_dir(cargo_toml.parent())

View file

@ -58,10 +58,6 @@ impl Tool {
probe_for_binary(path.join(self.name())) probe_for_binary(path.join(self.name()))
} }
pub fn path_in_or_discover(self, path: &Path) -> PathBuf {
probe_for_binary(path.join(self.name())).unwrap_or_else(|| self.path())
}
pub fn name(self) -> &'static str { pub fn name(self) -> &'static str {
match self { match self {
Tool::Cargo => "cargo", Tool::Cargo => "cargo",