]> git.lizzy.rs Git - rust.git/commitdiff
rustbuild: Add steps for linking a sysroot
authorAlex Crichton <alex@alexcrichton.com>
Thu, 25 Feb 2016 07:50:32 +0000 (23:50 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Sun, 28 Feb 2016 18:50:13 +0000 (10:50 -0800)
When cross compiling for a new host, we can't actually run the host compiler to
generate its own libs. In theory, however, all stage2 compilers (for any host)
will produce the same libraries, so we just require the build compiler to
produce the necessary host libraries and then we link those into place.

src/bootstrap/build/compile.rs
src/bootstrap/build/mod.rs
src/bootstrap/build/step.rs

index dc547f74db19b43e0b9d89635d2f605bcdef3442..3be4199352ca1e5da0f4e8e75680fded2a903803 100644 (file)
@@ -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
index 88ec6b72eddad3782fffd81300c46954888ec43a..4a77aeb97861f283bc2f22103625785e809fa7b0 100644 (file)
@@ -146,6 +146,14 @@ fn setup_job() {
                 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");
index f09a6ffbbf1caf3cb7ec0079f13e71bb1e7dff3f..49d418580a0b489c4a7c076e91ffafcf9739b5af 100644 (file)
@@ -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<Step> {
                 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<Step<'a>>) {
     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 @@ pub fn deps(&self, build: &'a Build) -> Vec<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)]
             }