Make it possible to run bootstrap on a different machine than the one it was built
- Default to trying git rev-parse for the root directory CARGO_MANIFEST_DIR is a path on the build machine, not the running machine. Don't require this to succeed, to allow building from a tarball; in that case fall back to CARGO_MANIFEST_DIR. - Set `initial_rustc` to a path based on the path of the running executable, not CARGO_MANIFEST_DIR. We only reset `initial_rustc` if we're sure this isn't the working tree bootstrap was originally built in, since I'm paranoid that setting this in other cases will cause things to break; it's not clear to me when $RUSTC differs from `build/$TARGET/stage0/bin/rustc` (maybe never? but better to be sure). Instead, only set this when a) We are not using a custom rustc. If someone has specified a custom rustc we should respect their wishes. b) We are in a checkout of rust-lang/rust other than the one bootstrap was built in.
This commit is contained in:
parent
63f6289db2
commit
55c040e529
1 changed files with 44 additions and 4 deletions
|
|
@ -772,21 +772,20 @@ impl Config {
|
|||
|
||||
// set by build.rs
|
||||
config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
|
||||
|
||||
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
// Undo `src/bootstrap`
|
||||
config.src = manifest_dir.parent().unwrap().parent().unwrap().to_owned();
|
||||
config.out = PathBuf::from("build");
|
||||
|
||||
config.initial_cargo = PathBuf::from(env!("CARGO"));
|
||||
config.initial_rustc = PathBuf::from(env!("RUSTC"));
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
pub fn parse(args: &[String]) -> Config {
|
||||
let flags = Flags::parse(&args);
|
||||
|
||||
let mut config = Config::default_opts();
|
||||
|
||||
// Set flags.
|
||||
config.exclude = flags.exclude.into_iter().map(|path| TaskPath::parse(path)).collect();
|
||||
config.include_default_paths = flags.include_default_paths;
|
||||
config.rustc_error_format = flags.rustc_error_format;
|
||||
|
|
@ -805,7 +804,41 @@ impl Config {
|
|||
config.llvm_profile_use = flags.llvm_profile_use;
|
||||
config.llvm_profile_generate = flags.llvm_profile_generate;
|
||||
|
||||
// Infer the rest of the configuration.
|
||||
|
||||
// Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary,
|
||||
// running on a completely machine from where it was compiled.
|
||||
let mut cmd = Command::new("git");
|
||||
// NOTE: we cannot support running from outside the repository because the only path we have available
|
||||
// is set at compile time, which can be wrong if bootstrap was downloaded from source.
|
||||
// We still support running outside the repository if we find we aren't in a git directory.
|
||||
cmd.arg("rev-parse").arg("--show-toplevel");
|
||||
// Discard stderr because we expect this to fail when building from a tarball.
|
||||
let output = cmd
|
||||
.stderr(std::process::Stdio::null())
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|output| if output.status.success() { Some(output) } else { None });
|
||||
if let Some(output) = output {
|
||||
let git_root = String::from_utf8(output.stdout).unwrap();
|
||||
config.src = PathBuf::from(git_root.trim().to_owned())
|
||||
} else {
|
||||
// We're building from a tarball, not git sources.
|
||||
// We don't support pre-downloaded bootstrap in this case.
|
||||
}
|
||||
|
||||
if cfg!(test) {
|
||||
// Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly.
|
||||
config.out = Path::new(
|
||||
&env::var_os("CARGO_TARGET_DIR").expect("cargo test directly is not supported"),
|
||||
)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
}
|
||||
|
||||
let stage0_json = t!(std::fs::read(&config.src.join("src").join("stage0.json")));
|
||||
|
||||
config.stage0_metadata = t!(serde_json::from_slice::<Stage0Metadata>(&stage0_json));
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -860,6 +893,7 @@ impl Config {
|
|||
config.config = toml_path;
|
||||
|
||||
let build = toml.build.unwrap_or_default();
|
||||
let has_custom_rustc = build.rustc.is_some();
|
||||
|
||||
set(&mut config.initial_rustc, build.rustc.map(PathBuf::from));
|
||||
set(&mut config.out, flags.build_dir.or_else(|| build.build_dir.map(PathBuf::from)));
|
||||
|
|
@ -870,6 +904,12 @@ impl Config {
|
|||
config.out = crate::util::absolute(&config.out);
|
||||
}
|
||||
|
||||
if !has_custom_rustc && !config.initial_rustc.starts_with(&config.out) {
|
||||
config.initial_rustc = config.out.join(config.build.triple).join("stage0/bin/rustc");
|
||||
config.initial_cargo = config.out.join(config.build.triple).join("stage0/bin/cargo");
|
||||
}
|
||||
|
||||
// NOTE: it's important this comes *after* we set `initial_rustc` just above.
|
||||
if config.dry_run {
|
||||
let dir = config.out.join("tmp-dry-run");
|
||||
t!(fs::create_dir_all(&dir));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue