]> git.lizzy.rs Git - rust.git/blobdiff - src/bootstrap/lib.rs
Rollup merge of #74464 - FedericoPonzi:fix-#67108, r=Manishearth
[rust.git] / src / bootstrap / lib.rs
index 783a64c3581f96a43b6b106bcebff0bdce9ec3ec..77820ef87e3b470399217ffcbcb9c33128bcfe76 100644 (file)
 use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed};
 use filetime::FileTime;
 
+use crate::config::TargetSelection;
 use crate::util::{exe, libdir, CiEnv};
 
 mod builder;
@@ -187,7 +188,7 @@ pub unsafe fn setup(_build: &mut crate::Build) {}
 #[derive(Eq, PartialOrd, Ord, PartialEq, Clone, Copy, Hash, Debug)]
 pub struct Compiler {
     stage: u32,
-    host: Interned<String>,
+    host: TargetSelection,
 }
 
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
@@ -236,9 +237,9 @@ pub struct Build {
     verbosity: usize,
 
     // Targets for which to build
-    build: Interned<String>,
-    hosts: Vec<Interned<String>>,
-    targets: Vec<Interned<String>>,
+    build: TargetSelection,
+    hosts: Vec<TargetSelection>,
+    targets: Vec<TargetSelection>,
 
     // Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
     initial_rustc: PathBuf,
@@ -248,10 +249,10 @@ pub struct Build {
 
     // Runtime state filled in later on
     // C/C++ compilers and archiver for all targets
-    cc: HashMap<Interned<String>, cc::Tool>,
-    cxx: HashMap<Interned<String>, cc::Tool>,
-    ar: HashMap<Interned<String>, PathBuf>,
-    ranlib: HashMap<Interned<String>, PathBuf>,
+    cc: HashMap<TargetSelection, cc::Tool>,
+    cxx: HashMap<TargetSelection, cc::Tool>,
+    ar: HashMap<TargetSelection, PathBuf>,
+    ranlib: HashMap<TargetSelection, PathBuf>,
     // Miscellaneous
     crates: HashMap<Interned<String>, Crate>,
     is_sudo: bool,
@@ -259,7 +260,7 @@ pub struct Build {
     delayed_failures: RefCell<Vec<String>>,
     prerelease_version: Cell<Option<u32>>,
     tool_artifacts:
-        RefCell<HashMap<Interned<String>, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
+        RefCell<HashMap<TargetSelection, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
 }
 
 #[derive(Debug)]
@@ -365,7 +366,7 @@ pub fn new(config: Config) -> Build {
             output(
                 Command::new(&config.initial_rustc)
                     .arg("--target")
-                    .arg(config.build)
+                    .arg(config.build.rustc_target_arg())
                     .arg("--print")
                     .arg("target-libdir"),
             )
@@ -453,7 +454,7 @@ pub fn new(config: Config) -> Build {
     }
 
     pub fn build_triple(&self) -> &[Interned<String>] {
-        unsafe { slice::from_raw_parts(&self.build, 1) }
+        slice::from_ref(&self.build.triple)
     }
 
     /// Executes the entire build, as configured by the flags and configuration.
@@ -558,7 +559,10 @@ fn cargo_dir(&self) -> &'static str {
     }
 
     fn tools_dir(&self, compiler: Compiler) -> PathBuf {
-        let out = self.out.join(&*compiler.host).join(format!("stage{}-tools-bin", compiler.stage));
+        let out = self
+            .out
+            .join(&*compiler.host.triple)
+            .join(format!("stage{}-tools-bin", compiler.stage));
         t!(fs::create_dir_all(&out));
         out
     }
@@ -575,54 +579,47 @@ fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
             Mode::ToolBootstrap => "-bootstrap-tools",
             Mode::ToolStd | Mode::ToolRustc => "-tools",
         };
-        self.out.join(&*compiler.host).join(format!("stage{}{}", compiler.stage, suffix))
+        self.out.join(&*compiler.host.triple).join(format!("stage{}{}", compiler.stage, suffix))
     }
 
     /// Returns the root output directory for all Cargo output in a given stage,
     /// running a particular compiler, whether or not we're building the
     /// standard library, and targeting the specified architecture.
-    fn cargo_out(&self, compiler: Compiler, mode: Mode, target: Interned<String>) -> PathBuf {
-        self.stage_out(compiler, mode).join(&*target).join(self.cargo_dir())
+    fn cargo_out(&self, compiler: Compiler, mode: Mode, target: TargetSelection) -> PathBuf {
+        self.stage_out(compiler, mode).join(&*target.triple).join(self.cargo_dir())
     }
 
     /// Root output directory for LLVM compiled for `target`
     ///
     /// Note that if LLVM is configured externally then the directory returned
     /// will likely be empty.
-    fn llvm_out(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("llvm")
+    fn llvm_out(&self, target: TargetSelection) -> PathBuf {
+        self.out.join(&*target.triple).join("llvm")
     }
 
-    fn lld_out(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("lld")
+    fn lld_out(&self, target: TargetSelection) -> PathBuf {
+        self.out.join(&*target.triple).join("lld")
     }
 
     /// Output directory for all documentation for a target
-    fn doc_out(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("doc")
+    fn doc_out(&self, target: TargetSelection) -> PathBuf {
+        self.out.join(&*target.triple).join("doc")
     }
 
     /// Output directory for all documentation for a target
-    fn compiler_doc_out(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("compiler-doc")
+    fn compiler_doc_out(&self, target: TargetSelection) -> PathBuf {
+        self.out.join(&*target.triple).join("compiler-doc")
     }
 
     /// Output directory for some generated md crate documentation for a target (temporary)
-    fn md_doc_out(&self, target: Interned<String>) -> Interned<PathBuf> {
-        INTERNER.intern_path(self.out.join(&*target).join("md-doc"))
-    }
-
-    /// Output directory for all crate documentation for a target (temporary)
-    ///
-    /// The artifacts here are then copied into `doc_out` above.
-    fn crate_doc_out(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("crate-docs")
+    fn md_doc_out(&self, target: TargetSelection) -> Interned<PathBuf> {
+        INTERNER.intern_path(self.out.join(&*target.triple).join("md-doc"))
     }
 
     /// Returns `true` if no custom `llvm-config` is set for the specified target.
     ///
     /// If no custom `llvm-config` was specified then Rust's llvm will be used.
-    fn is_rust_llvm(&self, target: Interned<String>) -> bool {
+    fn is_rust_llvm(&self, target: TargetSelection) -> bool {
         match self.config.target_config.get(&target) {
             Some(ref c) => c.llvm_config.is_none(),
             None => true,
@@ -630,13 +627,13 @@ fn is_rust_llvm(&self, target: Interned<String>) -> bool {
     }
 
     /// Returns the path to `FileCheck` binary for the specified target
-    fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
+    fn llvm_filecheck(&self, target: TargetSelection) -> PathBuf {
         let target_config = self.config.target_config.get(&target);
         if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) {
             s.to_path_buf()
         } else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
             let llvm_bindir = output(Command::new(s).arg("--bindir"));
-            let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target));
+            let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", target));
             if filecheck.exists() {
                 filecheck
             } else {
@@ -644,7 +641,7 @@ fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
                 // llvm subdirectory of the libdir.
                 let llvm_libdir = output(Command::new(s).arg("--libdir"));
                 let lib_filecheck =
-                    Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", &*target));
+                    Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", target));
                 if lib_filecheck.exists() {
                     lib_filecheck
                 } else {
@@ -669,18 +666,18 @@ fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
             } else {
                 base
             };
-            base.join("bin").join(exe("FileCheck", &*target))
+            base.join("bin").join(exe("FileCheck", target))
         }
     }
 
     /// Directory for libraries built from C/C++ code and shared between stages.
-    fn native_dir(&self, target: Interned<String>) -> PathBuf {
-        self.out.join(&*target).join("native")
+    fn native_dir(&self, target: TargetSelection) -> PathBuf {
+        self.out.join(&*target.triple).join("native")
     }
 
     /// Root output directory for rust_test_helpers library compiled for
     /// `target`
-    fn test_helpers_out(&self, target: Interned<String>) -> PathBuf {
+    fn test_helpers_out(&self, target: TargetSelection) -> PathBuf {
         self.native_dir(target).join("rust-test-helpers")
     }
 
@@ -693,7 +690,7 @@ fn add_rust_test_threads(&self, cmd: &mut Command) {
 
     /// Returns the libdir of the snapshot compiler.
     fn rustc_snapshot_libdir(&self) -> PathBuf {
-        self.rustc_snapshot_sysroot().join(libdir(&self.config.build))
+        self.rustc_snapshot_sysroot().join(libdir(self.config.build))
     }
 
     /// Returns the sysroot of the snapshot compiler.
@@ -791,13 +788,13 @@ fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> {
     }
 
     /// Returns the path to the C compiler for the target specified.
-    fn cc(&self, target: Interned<String>) -> &Path {
+    fn cc(&self, target: TargetSelection) -> &Path {
         self.cc[&target].path()
     }
 
     /// Returns a list of flags to pass to the C compiler for the target
     /// specified.
-    fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
+    fn cflags(&self, target: TargetSelection, which: GitRepo) -> Vec<String> {
         // Filter out -O and /O (the optimization flags) that we picked up from
         // cc-rs because the build scripts will determine that for themselves.
         let mut base = self.cc[&target]
@@ -818,7 +815,7 @@ fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
         // Work around an apparently bad MinGW / GCC optimization,
         // See: http://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html
         // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78936
-        if &*target == "i686-pc-windows-gnu" {
+        if &*target.triple == "i686-pc-windows-gnu" {
             base.push("-fno-omit-frame-pointer".into());
         }
 
@@ -836,17 +833,17 @@ fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
     }
 
     /// Returns the path to the `ar` archive utility for the target specified.
-    fn ar(&self, target: Interned<String>) -> Option<&Path> {
+    fn ar(&self, target: TargetSelection) -> Option<&Path> {
         self.ar.get(&target).map(|p| &**p)
     }
 
     /// Returns the path to the `ranlib` utility for the target specified.
-    fn ranlib(&self, target: Interned<String>) -> Option<&Path> {
+    fn ranlib(&self, target: TargetSelection) -> Option<&Path> {
         self.ranlib.get(&target).map(|p| &**p)
     }
 
     /// Returns the path to the C++ compiler for the target specified.
-    fn cxx(&self, target: Interned<String>) -> Result<&Path, String> {
+    fn cxx(&self, target: TargetSelection) -> Result<&Path, String> {
         match self.cxx.get(&target) {
             Some(p) => Ok(p.path()),
             None => {
@@ -856,12 +853,12 @@ fn cxx(&self, target: Interned<String>) -> Result<&Path, String> {
     }
 
     /// Returns the path to the linker for the given target if it needs to be overridden.
-    fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
+    fn linker(&self, target: TargetSelection, can_use_lld: bool) -> Option<&Path> {
         if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
         {
             Some(linker)
         } else if target != self.config.build
-            && util::use_host_linker(&target)
+            && util::use_host_linker(target)
             && !target.contains("msvc")
         {
             Some(self.cc(target))
@@ -873,7 +870,7 @@ fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
     }
 
     /// Returns if this target should statically link the C runtime, if specified
-    fn crt_static(&self, target: Interned<String>) -> Option<bool> {
+    fn crt_static(&self, target: TargetSelection) -> Option<bool> {
         if target.contains("pc-windows-msvc") {
             Some(true)
         } else {
@@ -882,7 +879,7 @@ fn crt_static(&self, target: Interned<String>) -> Option<bool> {
     }
 
     /// Returns the "musl root" for this `target`, if defined
-    fn musl_root(&self, target: Interned<String>) -> Option<&Path> {
+    fn musl_root(&self, target: TargetSelection) -> Option<&Path> {
         self.config
             .target_config
             .get(&target)
@@ -892,7 +889,7 @@ fn musl_root(&self, target: Interned<String>) -> Option<&Path> {
     }
 
     /// Returns the "musl libdir" for this `target`.
-    fn musl_libdir(&self, target: Interned<String>) -> Option<PathBuf> {
+    fn musl_libdir(&self, target: TargetSelection) -> Option<PathBuf> {
         let t = self.config.target_config.get(&target)?;
         if let libdir @ Some(_) = &t.musl_libdir {
             return libdir.clone();
@@ -901,18 +898,18 @@ fn musl_libdir(&self, target: Interned<String>) -> Option<PathBuf> {
     }
 
     /// Returns the sysroot for the wasi target, if defined
-    fn wasi_root(&self, target: Interned<String>) -> Option<&Path> {
+    fn wasi_root(&self, target: TargetSelection) -> Option<&Path> {
         self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p)
     }
 
     /// Returns `true` if this is a no-std `target`, if defined
-    fn no_std(&self, target: Interned<String>) -> Option<bool> {
+    fn no_std(&self, target: TargetSelection) -> Option<bool> {
         self.config.target_config.get(&target).map(|t| t.no_std)
     }
 
     /// Returns `true` if the target will be tested using the `remote-test-client`
     /// and `remote-test-server` binaries.
-    fn remote_tested(&self, target: Interned<String>) -> bool {
+    fn remote_tested(&self, target: TargetSelection) -> bool {
         self.qemu_rootfs(target).is_some()
             || target.contains("android")
             || env::var_os("TEST_DEVICE_ADDR").is_some()
@@ -923,7 +920,7 @@ fn remote_tested(&self, target: Interned<String>) -> bool {
     ///
     /// If `Some` is returned then that means that tests for this target are
     /// emulated with QEMU and binaries will need to be shipped to the emulator.
-    fn qemu_rootfs(&self, target: Interned<String>) -> Option<&Path> {
+    fn qemu_rootfs(&self, target: TargetSelection) -> Option<&Path> {
         self.config.target_config.get(&target).and_then(|t| t.qemu_rootfs.as_ref()).map(|p| &**p)
     }
 
@@ -955,7 +952,7 @@ fn extended_error_dir(&self) -> PathBuf {
     ///
     /// When all of these conditions are met the build will lift artifacts from
     /// the previous stage forward.
-    fn force_use_stage1(&self, compiler: Compiler, target: Interned<String>) -> bool {
+    fn force_use_stage1(&self, compiler: Compiler, target: TargetSelection) -> bool {
         !self.config.full_bootstrap
             && compiler.stage >= 2
             && (self.hosts.iter().any(|h| *h == target) || target == self.build)
@@ -1065,7 +1062,7 @@ fn llvm_tools_vers(&self) -> String {
         self.rust_version()
     }
 
-    fn llvm_link_tools_dynamically(&self, target: Interned<String>) -> bool {
+    fn llvm_link_tools_dynamically(&self, target: TargetSelection) -> bool {
         target.contains("linux-gnu") || target.contains("apple-darwin")
     }