about summary refs log tree commit diff
path: root/src/bootstrap/native.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/native.rs')
-rw-r--r--src/bootstrap/native.rs198
1 files changed, 129 insertions, 69 deletions
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 653606e5d24..987d70fd047 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -81,11 +81,11 @@ impl Step for Llvm {
 
         let (out_dir, llvm_config_ret_dir) = if emscripten {
             let dir = build.emscripten_llvm_out(target);
-            let config_dir = dir.join("bin");
+            let config_dir = dir.join("build/bin");
             (dir, config_dir)
         } else {
             (build.llvm_out(target),
-                build.llvm_out(build.config.build).join("bin"))
+                build.llvm_out(build.config.build).join("build/bin"))
         };
         let done_stamp = out_dir.join("llvm-finished-building");
         let build_llvm_config = llvm_config_ret_dir
@@ -110,9 +110,6 @@ impl Step for Llvm {
         // http://llvm.org/docs/CMake.html
         let root = if self.emscripten { "src/llvm-emscripten" } else { "src/llvm" };
         let mut cfg = cmake::Config::new(build.src.join(root));
-        if build.config.ninja {
-            cfg.generator("Ninja");
-        }
 
         let profile = match (build.config.llvm_optimize, build.config.llvm_release_debuginfo) {
             (false, _) => "Debug",
@@ -139,9 +136,7 @@ impl Step for Llvm {
 
         let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
 
-        cfg.target(&target)
-           .host(&build.build)
-           .out_dir(&out_dir)
+        cfg.out_dir(&out_dir)
            .profile(profile)
            .define("LLVM_ENABLE_ASSERTIONS", assertions)
            .define("LLVM_TARGETS_TO_BUILD", llvm_targets)
@@ -213,67 +208,7 @@ impl Step for Llvm {
             cfg.define("LLVM_NATIVE_BUILD", build.llvm_out(build.build).join("build"));
         }
 
-        let sanitize_cc = |cc: &Path| {
-            if target.contains("msvc") {
-                OsString::from(cc.to_str().unwrap().replace("\\", "/"))
-            } else {
-                cc.as_os_str().to_owned()
-            }
-        };
-
-        let configure_compilers = |cfg: &mut cmake::Config| {
-            // MSVC with CMake uses msbuild by default which doesn't respect these
-            // vars that we'd otherwise configure. In that case we just skip this
-            // entirely.
-            if target.contains("msvc") && !build.config.ninja {
-                return
-            }
-
-            let cc = build.cc(target);
-            let cxx = build.cxx(target).unwrap();
-
-            // Handle msvc + ninja + ccache specially (this is what the bots use)
-            if target.contains("msvc") &&
-               build.config.ninja &&
-               build.config.ccache.is_some() {
-                let mut cc = env::current_exe().expect("failed to get cwd");
-                cc.set_file_name("sccache-plus-cl.exe");
-
-               cfg.define("CMAKE_C_COMPILER", sanitize_cc(&cc))
-                  .define("CMAKE_CXX_COMPILER", sanitize_cc(&cc));
-               cfg.env("SCCACHE_PATH",
-                       build.config.ccache.as_ref().unwrap())
-                  .env("SCCACHE_TARGET", target);
-
-            // If ccache is configured we inform the build a little differently hwo
-            // to invoke ccache while also invoking our compilers.
-            } else if let Some(ref ccache) = build.config.ccache {
-               cfg.define("CMAKE_C_COMPILER", ccache)
-                  .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc))
-                  .define("CMAKE_CXX_COMPILER", ccache)
-                  .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx));
-            } else {
-               cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc))
-                  .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx));
-            }
-
-            cfg.build_arg("-j").build_arg(build.jobs().to_string());
-            cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
-            cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
-            if let Some(ar) = build.ar(target) {
-                if ar.is_absolute() {
-                    // LLVM build breaks if `CMAKE_AR` is a relative path, for some reason it
-                    // tries to resolve this path in the LLVM build directory.
-                    cfg.define("CMAKE_AR", sanitize_cc(ar));
-                }
-            }
-        };
-
-        configure_compilers(&mut cfg);
-
-        if env::var_os("SCCACHE_ERROR_LOG").is_some() {
-            cfg.env("RUST_LOG", "sccache=warn");
-        }
+        configure_cmake(build, target, &mut cfg);
 
         // FIXME: we don't actually need to build all LLVM tools and all LLVM
         //        libraries here, e.g. we just want a few components and a few
@@ -304,6 +239,131 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {
     panic!("\n\nbad LLVM version: {}, need >=3.9\n\n", version)
 }
 
+fn configure_cmake(build: &Build,
+                   target: Interned<String>,
+                   cfg: &mut cmake::Config) {
+    if build.config.ninja {
+        cfg.generator("Ninja");
+    }
+    cfg.target(&target)
+       .host(&build.config.build);
+
+    let sanitize_cc = |cc: &Path| {
+        if target.contains("msvc") {
+            OsString::from(cc.to_str().unwrap().replace("\\", "/"))
+        } else {
+            cc.as_os_str().to_owned()
+        }
+    };
+
+    // MSVC with CMake uses msbuild by default which doesn't respect these
+    // vars that we'd otherwise configure. In that case we just skip this
+    // entirely.
+    if target.contains("msvc") && !build.config.ninja {
+        return
+    }
+
+    let cc = build.cc(target);
+    let cxx = build.cxx(target).unwrap();
+
+    // Handle msvc + ninja + ccache specially (this is what the bots use)
+    if target.contains("msvc") &&
+       build.config.ninja &&
+       build.config.ccache.is_some() {
+        let mut cc = env::current_exe().expect("failed to get cwd");
+        cc.set_file_name("sccache-plus-cl.exe");
+
+       cfg.define("CMAKE_C_COMPILER", sanitize_cc(&cc))
+          .define("CMAKE_CXX_COMPILER", sanitize_cc(&cc));
+       cfg.env("SCCACHE_PATH",
+               build.config.ccache.as_ref().unwrap())
+          .env("SCCACHE_TARGET", target);
+
+    // If ccache is configured we inform the build a little differently hwo
+    // to invoke ccache while also invoking our compilers.
+    } else if let Some(ref ccache) = build.config.ccache {
+       cfg.define("CMAKE_C_COMPILER", ccache)
+          .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc))
+          .define("CMAKE_CXX_COMPILER", ccache)
+          .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx));
+    } else {
+       cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc))
+          .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx));
+    }
+
+    cfg.build_arg("-j").build_arg(build.jobs().to_string());
+    cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
+    let mut cxxflags = build.cflags(target).join(" ");
+    if build.config.llvm_static_stdcpp && !target.contains("windows") {
+        cxxflags.push_str(" -static-libstdc++");
+    }
+    cfg.define("CMAKE_CXX_FLAGS", cxxflags);
+    if let Some(ar) = build.ar(target) {
+        if ar.is_absolute() {
+            // LLVM build breaks if `CMAKE_AR` is a relative path, for some reason it
+            // tries to resolve this path in the LLVM build directory.
+            cfg.define("CMAKE_AR", sanitize_cc(ar));
+        }
+    }
+
+    if env::var_os("SCCACHE_ERROR_LOG").is_some() {
+        cfg.env("RUST_LOG", "sccache=warn");
+    }
+}
+
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct Lld {
+    pub target: Interned<String>,
+}
+
+impl Step for Lld {
+    type Output = PathBuf;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("src/tools/lld")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(Lld { target: run.target });
+    }
+
+    /// Compile LLVM for `target`.
+    fn run(self, builder: &Builder) -> PathBuf {
+        let target = self.target;
+        let build = builder.build;
+
+        let llvm_config = builder.ensure(Llvm {
+            target: self.target,
+            emscripten: false,
+        });
+
+        let out_dir = build.lld_out(target);
+        let done_stamp = out_dir.join("lld-finished-building");
+        if done_stamp.exists() {
+            return out_dir
+        }
+
+        let _folder = build.fold_output(|| "lld");
+        println!("Building LLD for {}", target);
+        let _time = util::timeit();
+        t!(fs::create_dir_all(&out_dir));
+
+        let mut cfg = cmake::Config::new(build.src.join("src/tools/lld"));
+        configure_cmake(build, target, &mut cfg);
+
+        cfg.out_dir(&out_dir)
+           .profile("Release")
+           .define("LLVM_CONFIG_PATH", llvm_config)
+           .define("LLVM_INCLUDE_TESTS", "OFF");
+
+        cfg.build();
+
+        t!(File::create(&done_stamp));
+        out_dir
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct TestHelpers {
     pub target: Interned<String>,