1
Fork 0

Auto merge of #121341 - GrigorenkoPV:bootstrap-rustup-cargo, r=onur-ozkan

bootstrap: don't resolve symlinks for initial_cargo

I have put the following in my `config.toml`:

```toml
# Includes one of the default files in src/bootstrap/defaults
profile = "compiler"
change-id = 121203

[build]
cargo = "/usr/bin/cargo"
rustc = "/usr/bin/rustc"
rustfmt = "/usr/bin/rustfmt"
```

I have rustup installed from Arch's repos, which has all of the above paths be symlinks to `/usr/bin/rustup`. This works just fine with the `argv[0]` trick that rustup uses.

However, `bootstrap` resolves symlinks to check whether `cargo` exists and then uses the resolved path, so it ends up calling `rustup` directly expecting it to behave like `cargo`. Which it doesn't.

This PR removes the canonicalization step, in turn fixing the issue, but sacrificing a pretty error message. However, this exact thing is checked by `x.py` in advance, so I hope it is not a big deal?
This commit is contained in:
bors 2024-02-23 03:44:47 +00:00
commit 71ff1c6246

View file

@ -22,6 +22,7 @@ use crate::utils::cache::{Interned, INTERNER};
use crate::utils::channel::{self, GitInfo}; use crate::utils::channel::{self, GitInfo};
use crate::utils::helpers::{exe, output, t}; use crate::utils::helpers::{exe, output, t};
use build_helper::exit; use build_helper::exit;
use build_helper::util::fail;
use semver::Version; use semver::Version;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize; use serde_derive::Deserialize;
@ -1418,7 +1419,7 @@ impl Config {
config.initial_rustc = if let Some(rustc) = rustc { config.initial_rustc = if let Some(rustc) = rustc {
if !flags.skip_stage0_validation { if !flags.skip_stage0_validation {
config.check_build_rustc_version(&rustc); config.check_stage0_version(&rustc, "rustc");
} }
PathBuf::from(rustc) PathBuf::from(rustc)
} else { } else {
@ -1426,11 +1427,15 @@ impl Config {
config.out.join(config.build.triple).join("stage0/bin/rustc") config.out.join(config.build.triple).join("stage0/bin/rustc")
}; };
config.initial_cargo = cargo config.initial_cargo = if let Some(cargo) = cargo {
.map(|cargo| { if !flags.skip_stage0_validation {
t!(PathBuf::from(cargo).canonicalize(), "`initial_cargo` not found on disk") config.check_stage0_version(&cargo, "cargo");
}) }
.unwrap_or_else(|| config.out.join(config.build.triple).join("stage0/bin/cargo")); PathBuf::from(cargo)
} else {
config.download_beta_toolchain();
config.out.join(config.build.triple).join("stage0/bin/cargo")
};
// NOTE: it's important this comes *after* we set `initial_rustc` just above. // NOTE: it's important this comes *after* we set `initial_rustc` just above.
if config.dry_run() { if config.dry_run() {
@ -2286,39 +2291,37 @@ impl Config {
} }
} }
pub fn check_build_rustc_version(&self, rustc_path: &str) { // check rustc/cargo version is same or lower with 1 apart from the building one
pub fn check_stage0_version(&self, program_path: &str, component_name: &'static str) {
if self.dry_run() { if self.dry_run() {
return; return;
} }
// check rustc version is same or lower with 1 apart from the building one let stage0_output = output(Command::new(program_path).arg("--version"));
let mut cmd = Command::new(rustc_path); let mut stage0_output = stage0_output.lines().next().unwrap().split(' ');
cmd.arg("--version");
let rustc_output = output(&mut cmd) let stage0_name = stage0_output.next().unwrap();
.lines() if stage0_name != component_name {
.next() fail(&format!(
.unwrap() "Expected to find {component_name} at {program_path} but it claims to be {stage0_name}"
.split(' ') ));
.nth(1) }
.unwrap()
.split('-') let stage0_version =
.next() Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
.unwrap() .unwrap();
.to_owned();
let rustc_version = Version::parse(rustc_output.trim()).unwrap();
let source_version = let source_version =
Version::parse(fs::read_to_string(self.src.join("src/version")).unwrap().trim()) Version::parse(fs::read_to_string(self.src.join("src/version")).unwrap().trim())
.unwrap(); .unwrap();
if !(source_version == rustc_version if !(source_version == stage0_version
|| (source_version.major == rustc_version.major || (source_version.major == stage0_version.major
&& (source_version.minor == rustc_version.minor && (source_version.minor == stage0_version.minor
|| source_version.minor == rustc_version.minor + 1))) || source_version.minor == stage0_version.minor + 1)))
{ {
let prev_version = format!("{}.{}.x", source_version.major, source_version.minor - 1); let prev_version = format!("{}.{}.x", source_version.major, source_version.minor - 1);
eprintln!( fail(&format!(
"Unexpected rustc version: {rustc_version}, we should use {prev_version}/{source_version} to build source with {source_version}" "Unexpected {component_name} version: {stage0_version}, we should use {prev_version}/{source_version} to build source with {source_version}"
); ));
exit!(1);
} }
} }