diff --git a/src/bootstrap/build/compile.rs b/src/bootstrap/build/compile.rs index dc547f74db1..3be4199352c 100644 --- a/src/bootstrap/build/compile.rs +++ b/src/bootstrap/build/compile.rs @@ -58,6 +58,30 @@ pub fn std<'a>(build: &'a Build, stage: u32, target: &str, } build.run(&mut cargo); + std_link(build, stage, target, compiler, host); +} + +/// Link all libstd rlibs/dylibs into the sysroot location. +/// +/// Links those artifacts generated in the given `stage` for `target` produced +/// by `compiler` into `host`'s sysroot. +pub fn std_link(build: &Build, + stage: u32, + target: &str, + compiler: &Compiler, + host: &str) { + let libdir = build.sysroot_libdir(stage, host, target); + let out_dir = build.cargo_out(stage, compiler.host, true, target); + + // If we're linking one compiler host's output into another, then we weren't + // called from the `std` method above. In that case we clean out what's + // already there and then also link compiler-rt into place. + if host != compiler.host { + let _ = fs::remove_dir_all(&libdir); + t!(fs::create_dir_all(&libdir)); + t!(fs::hard_link(&build.compiler_rt_built.borrow()[target], + libdir.join(staticlib("compiler-rt", target)))); + } add_to_sysroot(&out_dir, &libdir); } @@ -150,8 +174,21 @@ pub fn rustc<'a>(build: &'a Build, stage: u32, target: &str, } build.run(&mut cargo); - let sysroot_libdir = build.sysroot_libdir(stage, host, target); - add_to_sysroot(&out_dir, &sysroot_libdir); + rustc_link(build, stage, target, compiler, compiler.host); +} + +/// Link all librustc rlibs/dylibs into the sysroot location. +/// +/// Links those artifacts generated in the given `stage` for `target` produced +/// by `compiler` into `host`'s sysroot. +pub fn rustc_link(build: &Build, + stage: u32, + target: &str, + compiler: &Compiler, + host: &str) { + let libdir = build.sysroot_libdir(stage, host, target); + let out_dir = build.cargo_out(stage, compiler.host, false, target); + add_to_sysroot(&out_dir, &libdir); } /// Cargo's output path for the standard library in a given stage, compiled diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index 88ec6b72edd..4a77aeb9786 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -146,6 +146,14 @@ impl Build { Librustc { stage, compiler } => { compile::rustc(self, stage, target.target, &compiler); } + LibstdLink { stage, compiler, host } => { + compile::std_link(self, stage, target.target, + &compiler, host); + } + LibrustcLink { stage, compiler, host } => { + compile::rustc_link(self, stage, target.target, + &compiler, host); + } Rustc { stage: 0 } => { assert!(target.target == self.config.build, "only have one stage0 compiler"); diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index f09a6ffbbf1..49d418580a0 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -32,6 +32,19 @@ macro_rules! targets { (libstd, Libstd { stage: u32, compiler: Compiler<'a> }), (librustc, Librustc { stage: u32, compiler: Compiler<'a> }), + // Links the standard library/librustc produced by the compiler + // provided into the host's directory also provided. + (libstd_link, LibstdLink { + stage: u32, + compiler: Compiler<'a>, + host: &'a str + }), + (librustc_link, LibrustcLink { + stage: u32, + compiler: Compiler<'a>, + host: &'a str + }), + // Steps for long-running native builds. Ideally these wouldn't // actually exist and would be part of build scripts, but for now // these are here. @@ -107,13 +120,25 @@ fn top_level(build: &Build) -> Vec { continue } let host = t.target(host); - targets.push(host.librustc(stage, t.compiler(stage))); + if host.target == build.config.build { + targets.push(host.librustc(stage, host.compiler(stage))); + } else { + targets.push(host.librustc_link(stage, t.compiler(stage), + host.target)); + } for target in build.config.target.iter() { if !build.flags.target.contains(target) { continue } - targets.push(host.target(target) - .libstd(stage, t.compiler(stage))); + + if host.target == build.config.build { + targets.push(host.target(target) + .libstd(stage, host.compiler(stage))); + } else { + targets.push(host.target(target) + .libstd_link(stage, t.compiler(stage), + host.target)); + } } } } @@ -128,10 +153,14 @@ fn add_steps<'a>(build: &'a Build, target: &Step<'a>, targets: &mut Vec>) { for step in build.flags.step.iter() { - let compiler = host.compiler(stage); + let compiler = host.target(&build.config.build).compiler(stage); match &step[..] { "libstd" => targets.push(target.libstd(stage, compiler)), "librustc" => targets.push(target.librustc(stage, compiler)), + "libstd-link" => targets.push(target.libstd_link(stage, compiler, + host.target)), + "librustc-link" => targets.push(target.librustc_link(stage, compiler, + host.target)), "rustc" => targets.push(host.rustc(stage)), "llvm" => targets.push(target.llvm(())), "compiler-rt" => targets.push(target.compiler_rt(())), @@ -179,6 +208,14 @@ impl<'a> Step<'a> { vec![self.compiler_rt(()), self.rustc(compiler.stage).target(compiler.host)] } + Source::LibrustcLink { stage, compiler, host } => { + vec![self.librustc(stage, compiler), + self.libstd_link(stage, compiler, host)] + } + Source::LibstdLink { stage, compiler, host } => { + vec![self.libstd(stage, compiler), + self.target(host).rustc(stage)] + } Source::CompilerRt { _dummy } => { vec![self.llvm(()).target(&build.config.build)] }