Skip to content

Replace Windows custom toolchain hack #1499

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

Closed
wants to merge 1 commit into from
Closed
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
34 changes: 3 additions & 31 deletions src/rustup-mock/src/mock_bin_src.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,6 @@ fn main() {
let mut hash_file = PathBuf::from(format!("{}.version-hash", me.display()));
let mut version = String::new();
let mut hash = String::new();
if !version_file.exists() {
// There's a "MAJOR HACKS" statement in `toolchain.rs` right
// now where custom toolchains use a `cargo.exe` that's
// temporarily located elsewhere so they can execute the correct
// `rustc.exe`. This means that our dummy version files may not
// be just next to use.
//
// Detect this here and work around it.
assert!(cfg!(windows));
assert!(env::var_os("RUSTUP_TOOLCHAIN").is_some());
let mut alt = me.clone();
alt.pop(); // remove our filename
assert!(alt.ends_with("fallback"));
alt.pop(); // pop 'fallback'
alt.push("toolchains");

let mut part = PathBuf::from("bin");
part.push(me.file_name().unwrap());

let path = alt.read_dir().unwrap()
.map(|e| e.unwrap().path().join(&part))
.filter(|p| p.exists())
.find(|p| equivalent(&p, &me))
.unwrap();

version_file = format!("{}.version", path.display()).into();
hash_file = format!("{}.version-hash", path.display()).into();
}
File::open(&version_file).unwrap().read_to_string(&mut version).unwrap();
File::open(&hash_file).unwrap().read_to_string(&mut hash).unwrap();
println!("{} ({})", version, hash);
Expand All @@ -57,9 +29,9 @@ fn main() {
}
Some("--call-rustc") => {
// Used by the fallback_cargo_calls_correct_rustc test. Tests that
// the environment has been set up right such that invoking rustc
// will actually invoke the wrapper
let rustc = &format!("rustc{}", EXE_SUFFIX);
// the environment has been set up right such that invoking cargo
// will invoke the correct rustc executable.
let rustc = env::var_os("RUSTC").unwrap_or(format!("rustc{}", EXE_SUFFIX).into());
Command::new(rustc).arg("--version").status().unwrap();
}
_ => panic!("bad mock proxy commandline"),
Expand Down
40 changes: 14 additions & 26 deletions src/rustup/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,38 +373,26 @@ impl<'a> Toolchain<'a> {
return Err(ErrorKind::ToolchainNotInstalled(primary_toolchain.name.to_owned()).into());
}

let src_file = self.path.join("bin").join(format!("cargo{}", EXE_SUFFIX));

// MAJOR HACKS: Copy cargo.exe to its own directory on windows before
// running it. This is so that the fallback cargo, when it in turn runs
// rustc.exe, will run the rustc.exe out of the PATH environment
// variable, _not_ the rustc.exe sitting in the same directory as the
// fallback. See the `fallback_cargo_calls_correct_rustc` testcase and
// PR 812.
let exe_path = self.path.join("bin").join(format!("cargo{}", EXE_SUFFIX));

let mut cmd = Command::new(exe_path);
self.set_env(&mut cmd);
cmd.env("RUSTUP_TOOLCHAIN", &primary_toolchain.name);

// Set the RUSTC environment variable to the primary toolchain binary
// on Windows. This is so that the fallback cargo will run that executable
// and _not_ the rustc.exe sitting in the same directory. See the
// `fallback_cargo_calls_correct_rustc` testcase.
//
// On Windows, spawning a process will search the running application's
// directory for the exe to spawn before searching PATH, and we don't want
// it to do that, because cargo's directory contains the _wrong_ rustc. See
// the documantation for the lpCommandLine argument of CreateProcess.
let exe_path = if cfg!(windows) {
use std::fs;
let fallback_dir = self.cfg.rustup_dir.join("fallback");
fs::create_dir_all(&fallback_dir)
.chain_err(|| "unable to create dir to hold fallback exe")?;
let fallback_file = fallback_dir.join("cargo.exe");
if fallback_file.exists() {
fs::remove_file(&fallback_file)
.chain_err(|| "unable to unlink old fallback exe")?;
if cfg!(windows) {
if env::var_os("RUSTC").is_none() {
cmd.env("RUSTC", primary_toolchain.binary_file("rustc"));
}
fs::hard_link(&src_file, &fallback_file)
.chain_err(|| "unable to hard link fallback exe")?;
fallback_file
} else {
src_file
};
let mut cmd = Command::new(exe_path);
self.set_env(&mut cmd);
cmd.env("RUSTUP_TOOLCHAIN", &primary_toolchain.name);
}
Ok(cmd)
}

Expand Down