diff --git a/Cargo.lock b/Cargo.lock index 45bdcb2bcfc1..5475725174ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.73" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cert_storage" diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 55b0e45d2964..ffd1bfad31d7 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -785,6 +785,11 @@ who = "Mike Hommey " criteria = "safe-to-deploy" delta = "0.15.2 -> 0.15.3" +[[audits.cc]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "1.0.73 -> 1.0.78" + [[audits.chardetng]] who = "Henri Sivonen " criteria = "safe-to-deploy" diff --git a/third_party/rust/cc/.cargo-checksum.json b/third_party/rust/cc/.cargo-checksum.json index a7f8f2fe7afe..4dc2fe2390fc 100644 --- a/third_party/rust/cc/.cargo-checksum.json +++ b/third_party/rust/cc/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"739aae86d1e7096fc84b9a6273cc49635503a4ee87b3a4b6601f569880866b29","Cargo.toml":"ccfa92dd53511178ef95aa87b2dcbdd45e23f9f8a8454e455d7da8e08feab4b5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"1fd66e1fe6d618030b9452c667e89d7a31b27331ad831d83b41f9762fd6858d4","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"bcdaf1c28b71e6ef889c6b08d1ce9d7c0761344a677f523bc4c3cd297957f804","src/lib.rs":"38970d678de0efb4b5e2978265daa8a613a1db35fc42e669621b03fc56d5b138","src/registry.rs":"3cc1b5a50879fa751572878ae1d0afbfc960c11665258492754b2c8bccb0ff5d","src/setup_config.rs":"7014103587d3382eac599cb76f016e2609b8140970861b2237982d1db24af265","src/vs_instances.rs":"2d3f8278a803b0e7052f4eeb1979b29f963dd0143f4458e2cb5f33c4e5f0963b","src/winapi.rs":"ea8b7edbb9ff87957254f465c2334e714c5d6b3b19a8d757c48ea7ca0881c50c","src/windows_registry.rs":"4645453198766c7486fc9b8782b06cfd0f94cbbcb3482413173e73234a447518","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"a3c8d116973bb16066bf6ec4de5143183f97de7aad085d85f8118a2eaac3e1e0","tests/test.rs":"65c073e0e2cf4aa0433066102788e9f57442719e6f32f5ad5248aa7132bb4597"},"package":"2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"} \ No newline at end of file +{"files":{"Cargo.lock":"23c26d62ba5114f5ac6e7ffa3ea233cea77e5cb7f98d9f056f40fe2c49971f67","Cargo.toml":"fd4b39488866b6717476fadc460ff91c89511628080769516eec452c0def8bc7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"58af5106352aafa62175a90f8a5f25fa114028bf909220dc0735d79745999ec1","src/bin/gcc-shim.rs":"b77907875029494b6288841c3aed2e4939ed40708c7f597fca5c9e2570490ca6","src/com.rs":"29d0dee08a656ab1a4cc3e5fe24542e0fab5c1373cbc9b05059f7572cf9b8313","src/lib.rs":"e0cc228db97675d6a0d86b219a20e9e48925a1ccbfd9e9fd038ccf6ef129957e","src/registry.rs":"98ae2b71781acc49297e5544fa0cf059f735636f8f1338edef8dbf7232443945","src/setup_config.rs":"72deaf1927c0b713fd5c2b2d5b8f0ea3a303a00fda1579427895cac26a94122d","src/vs_instances.rs":"2d3f8278a803b0e7052f4eeb1979b29f963dd0143f4458e2cb5f33c4e5f0963b","src/winapi.rs":"e128e95b2d39ae7a02f54a7e25d33c488c14759b9f1a50a449e10545856950c3","src/windows_registry.rs":"c0340379c1f540cf96f45bbd4cf8fc28db555826f30ac937b75b87e4377b716b","tests/cc_env.rs":"e02b3b0824ad039b47e4462c5ef6dbe6c824c28e7953af94a0f28f7b5158042e","tests/cflags.rs":"57f06eb5ce1557e5b4a032d0c4673e18fbe6f8d26c1deb153126e368b96b41b3","tests/cxxflags.rs":"c2c6c6d8a0d7146616fa1caed26876ee7bc9fcfffd525eb4743593cade5f3371","tests/support/mod.rs":"a3c8d116973bb16066bf6ec4de5143183f97de7aad085d85f8118a2eaac3e1e0","tests/test.rs":"61fb35ae6dd5cf506ada000bdd82c92e9f8eac9cc053b63e83d3f897436fbf8f"},"package":"a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"} \ No newline at end of file diff --git a/third_party/rust/cc/Cargo.lock b/third_party/rust/cc/Cargo.lock index 524a6cd61a31..2d065bc6a879 100644 --- a/third_party/rust/cc/Cargo.lock +++ b/third_party/rust/cc/Cargo.lock @@ -10,7 +10,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.78" dependencies = [ "jobserver", "tempfile", @@ -24,9 +24,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -42,24 +42,24 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] [[package]] name = "libc" -version = "0.2.118" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] diff --git a/third_party/rust/cc/Cargo.toml b/third_party/rust/cc/Cargo.toml index ad0ec2138568..c4ec0bf79d71 100644 --- a/third_party/rust/cc/Cargo.toml +++ b/third_party/rust/cc/Cargo.toml @@ -12,20 +12,26 @@ [package] edition = "2018" name = "cc" -version = "1.0.73" +version = "1.0.78" authors = ["Alex Crichton "] -exclude = ["/.github", "/.travis.yml", "/appveyor.yml"] -description = "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n" -homepage = "https://github.com/alexcrichton/cc-rs" +exclude = ["/.github"] +description = """ +A build-time dependency for Cargo build scripts to assist in invoking the native +C compiler to compile native C code into a static archive to be linked into Rust +code. +""" +homepage = "https://github.com/rust-lang/cc-rs" documentation = "https://docs.rs/cc" readme = "README.md" keywords = ["build-dependencies"] categories = ["development-tools::build-utils"] -license = "MIT/Apache-2.0" -repository = "https://github.com/alexcrichton/cc-rs" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/cc-rs" + [dependencies.jobserver] version = "0.1.16" optional = true + [dev-dependencies.tempfile] version = "3" diff --git a/third_party/rust/cc/README.md b/third_party/rust/cc/README.md index b52e095b9405..863540d2d941 100644 --- a/third_party/rust/cc/README.md +++ b/third_party/rust/cc/README.md @@ -135,12 +135,12 @@ required varies per platform, but there are three broad categories: the appropriate developer tools shell. * Windows platforms targeting MinGW (e.g. your target triple ends in `-gnu`) require `cc` to be available in `PATH`. We recommend the - [MinGW-w64](http://mingw-w64.org) distribution, which is using the - [Win-builds](http://win-builds.org) installation system. + [MinGW-w64](https://www.mingw-w64.org/) distribution, which is using the + [Win-builds](http://win-builds.org/) installation system. You may also acquire it via [MSYS2](https://www.msys2.org/), as explained [here][msys2-help]. Make sure to install the appropriate architecture corresponding to your installation of - rustc. GCC from older [MinGW](http://www.mingw.org) project is compatible + rustc. GCC from older [MinGW](http://www.mingw.org/) project is compatible only with 32-bit rust compiler. [msys2-help]: https://github.com/rust-lang/rust#building-on-windows diff --git a/third_party/rust/cc/src/com.rs b/third_party/rust/cc/src/com.rs index a5f2afedf4a2..843247e5884b 100644 --- a/third_party/rust/cc/src/com.rs +++ b/third_party/rust/cc/src/com.rs @@ -1,7 +1,7 @@ // Copyright © 2017 winapi-rs developers // Licensed under the Apache License, Version 2.0 -// or the MIT license -// , at your option. +// or the MIT license +// , at your option. // All files in the project carrying such notice may not be copied, modified, or distributed // except according to those terms. diff --git a/third_party/rust/cc/src/lib.rs b/third_party/rust/cc/src/lib.rs index e3a2b98b03e0..1ebd2cc7a577 100644 --- a/third_party/rust/cc/src/lib.rs +++ b/third_party/rust/cc/src/lib.rs @@ -56,11 +56,12 @@ #![allow(deprecated)] #![deny(missing_docs)] -use std::collections::HashMap; +use std::collections::{hash_map, HashMap}; use std::env; use std::ffi::{OsStr, OsString}; -use std::fmt::{self, Display}; +use std::fmt::{self, Display, Formatter}; use std::fs; +use std::hash::Hasher; use std::io::{self, BufRead, BufReader, Read, Write}; use std::path::{Component, Path, PathBuf}; use std::process::{Child, Command, Stdio}; @@ -97,6 +98,7 @@ pub struct Build { flags_supported: Vec, known_flag_support_status: Arc>>, ar_flags: Vec, + asm_flags: Vec, no_default_flags: bool, files: Vec, cpp: bool, @@ -114,6 +116,7 @@ pub struct Build { compiler: Option, archiver: Option, cargo_metadata: bool, + link_lib_modifiers: Vec, pic: Option, use_plt: Option, static_crt: Option, @@ -124,6 +127,7 @@ pub struct Build { extra_warnings: Option, env_cache: Arc>>>, apple_sdk_root_cache: Arc>>, + emit_rerun_if_env_changed: bool, } /// Represents the types of errors that may occur while using cc-rs. @@ -168,7 +172,7 @@ impl From for Error { } impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", self.kind, self.message) } } @@ -212,13 +216,17 @@ enum ToolFamily { impl ToolFamily { /// What the flag to request debug info for this family of tools look like - fn add_debug_flags(&self, cmd: &mut Tool) { + fn add_debug_flags(&self, cmd: &mut Tool, dwarf_version: Option) { match *self { ToolFamily::Msvc { .. } => { cmd.push_cc_arg("-Z7".into()); } ToolFamily::Gnu | ToolFamily::Clang => { - cmd.push_cc_arg("-g".into()); + cmd.push_cc_arg( + dwarf_version + .map_or_else(|| "-g".into(), |v| format!("-gdwarf-{}", v)) + .into(), + ); } } } @@ -293,6 +301,7 @@ impl Build { flags_supported: Vec::new(), known_flag_support_status: Arc::new(Mutex::new(HashMap::new())), ar_flags: Vec::new(), + asm_flags: Vec::new(), no_default_flags: false, files: Vec::new(), shared_flag: None, @@ -312,6 +321,7 @@ impl Build { compiler: None, archiver: None, cargo_metadata: true, + link_lib_modifiers: Vec::new(), pic: None, use_plt: None, static_crt: None, @@ -320,6 +330,7 @@ impl Build { warnings_into_errors: false, env_cache: Arc::new(Mutex::new(HashMap::new())), apple_sdk_root_cache: Arc::new(Mutex::new(HashMap::new())), + emit_rerun_if_env_changed: true, } } @@ -426,6 +437,25 @@ impl Build { self } + /// Add a flag that will only be used with assembly files. + /// + /// The flag will be applied to input files with either a `.s` or + /// `.asm` extension (case insensitive). + /// + /// # Example + /// + /// ```no_run + /// cc::Build::new() + /// .asm_flag("-Wa,-defsym,abc=1") + /// .file("src/foo.S") // The asm flag will be applied here + /// .file("src/bar.c") // The asm flag will not be applied here + /// .compile("foo"); + /// ``` + pub fn asm_flag(&mut self, flag: &str) -> &mut Build { + self.asm_flags.push(flag.to_string()); + self + } + fn ensure_check_file(&self) -> Result { let out_dir = self.get_out_dir()?; let src = if self.cuda { @@ -475,6 +505,9 @@ impl Build { .debug(false) .cpp(self.cpp) .cuda(self.cuda); + if let Some(ref c) = self.compiler { + cfg.compiler(c.clone()); + } let mut compiler = cfg.try_get_compiler()?; // Clang uses stderr for verbose output, which yields a false positive @@ -892,12 +925,23 @@ impl Build { /// - `rustc-link-search=native=`*target folder* /// - When target is MSVC, the ATL-MFC libs are added via `rustc-link-search=native=` /// - When C++ is enabled, the C++ stdlib is added via `rustc-link-lib` + /// - If `emit_rerun_if_env_changed` is not `false`, `rerun-if-env-changed=`*env* /// pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Build { self.cargo_metadata = cargo_metadata; self } + /// Adds a native library modifier that will be added to the + /// `rustc-link-lib=static:MODIFIERS=LIBRARY_NAME` metadata line + /// emitted for cargo if `cargo_metadata` is enabled. + /// See https://doc.rust-lang.org/rustc/command-line-arguments.html#-l-link-the-generated-crate-to-a-native-library + /// for the list of modifiers accepted by rustc. + pub fn link_lib_modifier(&mut self, link_lib_modifier: &str) -> &mut Build { + self.link_lib_modifiers.push(link_lib_modifier.to_string()); + self + } + /// Configures whether the compiler will emit position independent code. /// /// This option defaults to `false` for `windows-gnu` and bare metal targets and @@ -922,6 +966,17 @@ impl Build { self } + /// Define whether metadata should be emitted for cargo to detect environment + /// changes that should trigger a rebuild. + /// + /// This has no effect if the `cargo_metadata` option is `false`. + /// + /// This option defaults to `true`. + pub fn emit_rerun_if_env_changed(&mut self, emit_rerun_if_env_changed: bool) -> &mut Build { + self.emit_rerun_if_env_changed = emit_rerun_if_env_changed; + self + } + /// Configures whether the /MT flag or the /MD flag will be passed to msvc build tools. /// /// This option defaults to `false`, and affect only msvc targets. @@ -969,7 +1024,24 @@ impl Build { let mut objects = Vec::new(); for file in self.files.iter() { - let obj = dst.join(file).with_extension("o"); + let obj = if file.has_root() { + // If `file` is an absolute path, prefix the `basename` + // with the `dirname`'s hash to ensure name uniqueness. + let basename = file + .file_name() + .ok_or_else(|| Error::new(ErrorKind::InvalidArgument, "file_name() failure"))? + .to_string_lossy(); + let dirname = file + .parent() + .ok_or_else(|| Error::new(ErrorKind::InvalidArgument, "parent() failure"))? + .to_string_lossy(); + let mut hasher = hash_map::DefaultHasher::new(); + hasher.write(dirname.to_string().as_bytes()); + dst.join(format!("{:016x}-{}", hasher.finish(), basename)) + .with_extension("o") + } else { + dst.join(file).with_extension("o") + }; let obj = if !obj.starts_with(&dst) { dst.join(obj.file_name().ok_or_else(|| { Error::new(ErrorKind::IOError, "Getting object file details failed.") @@ -1014,7 +1086,12 @@ impl Build { } } - self.print(&format!("cargo:rustc-link-lib=static={}", lib_name)); + if self.link_lib_modifiers.is_empty() { + self.print(&format!("cargo:rustc-link-lib=static={}", lib_name)); + } else { + let m = self.link_lib_modifiers.join(","); + self.print(&format!("cargo:rustc-link-lib=static:{}={}", m, lib_name)); + } self.print(&format!("cargo:rustc-link-search=native={}", dst.display())); // Add specific C++ libraries, if enabled. @@ -1280,12 +1357,14 @@ impl Build { } fn compile_object(&self, obj: &Object) -> Result<(), Error> { - let is_asm = obj.src.extension().and_then(|s| s.to_str()) == Some("asm"); + let asm_ext = AsmFileExt::from_path(&obj.src); + let is_asm = asm_ext.is_some(); let target = self.get_target()?; let msvc = target.contains("msvc"); let compiler = self.try_get_compiler()?; let clang = compiler.family == ToolFamily::Clang; - let (mut cmd, name) = if msvc && is_asm { + + let (mut cmd, name) = if msvc && asm_ext == Some(AsmFileExt::DotAsm) { self.msvc_macro_assembler()? } else { let mut cmd = compiler.to_command(); @@ -1308,9 +1387,19 @@ impl Build { if !msvc || !is_asm || !is_arm { cmd.arg("-c"); } - if self.cuda && self.files.len() > 1 { + if self.cuda && self.cuda_file_count() > 1 { cmd.arg("--device-c"); } + if is_asm { + cmd.args(&self.asm_flags); + } + if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_asm { + // #513: For `clang-cl`, separate flags/options from the input file. + // When cross-compiling macOS -> Windows, this avoids interpreting + // common `/Users/...` paths as the `/U` flag and triggering + // `-Wslash-u-filename` warning. + cmd.arg("--"); + } cmd.arg(&obj.src); if cfg!(target_os = "macos") { self.fix_env_for_apple_os(&mut cmd)?; @@ -1522,7 +1611,7 @@ impl Build { cmd.push_opt_unless_duplicate("-DANDROID".into()); } - if !target.contains("apple-ios") { + if !target.contains("apple-ios") && !target.contains("apple-watchos") { cmd.push_cc_arg("-ffunction-sections".into()); cmd.push_cc_arg("-fdata-sections".into()); } @@ -1548,7 +1637,7 @@ impl Build { cmd.args.push("-G".into()); } let family = cmd.family; - family.add_debug_flags(cmd); + family.add_debug_flags(cmd, self.get_dwarf_version()); } if self.get_force_frame_pointer() { @@ -1574,7 +1663,7 @@ impl Build { map_darwin_target_from_rust_to_compiler_architecture(target) { cmd.args - .push(format!("--target={}-apple-ios13.0-macabi", arch).into()); + .push(format!("--target={}-apple-ios-macabi", arch).into()); } } else if target.contains("ios-sim") { if let Some(arch) = @@ -1590,6 +1679,20 @@ impl Build { .into(), ); } + } else if target.contains("watchos-sim") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let deployment_target = env::var("WATCHOS_DEPLOYMENT_TARGET") + .unwrap_or_else(|_| "5.0".into()); + cmd.args.push( + format!( + "--target={}-apple-watchos{}-simulator", + arch, deployment_target + ) + .into(), + ); + } } else if target.starts_with("riscv64gc-") { cmd.args.push( format!("--target={}", target.replace("riscv64gc", "riscv64")).into(), @@ -1607,7 +1710,7 @@ impl Build { cmd.args.push("--target=aarch64-unknown-windows-gnu".into()) } } else { - cmd.args.push(format!("--target={}", target).into()); + cmd.push_cc_arg(format!("--target={}", target).into()); } } } @@ -1849,8 +1952,8 @@ impl Build { } } - if target.contains("apple-ios") { - self.ios_flags(cmd)?; + if target.contains("apple-ios") || target.contains("apple-watchos") { + self.ios_watchos_flags(cmd)?; } if self.static_flag.unwrap_or(false) { @@ -1906,8 +2009,16 @@ impl Build { cmd.arg("-I").arg(directory); } if target.contains("aarch64") || target.contains("arm") { + if self.get_debug() { + cmd.arg("-g"); + } + println!("cargo:warning=The MSVC ARM assemblers do not support -D flags"); } else { + if self.get_debug() { + cmd.arg("-Zi"); + } + for &(ref key, ref value) in self.definitions.iter() { if let Some(ref value) = *value { cmd.arg(&format!("-D{}={}", key, value)); @@ -1944,7 +2055,7 @@ impl Build { self.assemble_progressive(dst, chunk)?; } - if self.cuda { + if self.cuda && self.cuda_file_count() > 0 { // Link the device-side code and add it to the target library, // so that non-CUDA linker can link the final binary. @@ -2043,18 +2154,37 @@ impl Build { Ok(()) } - fn ios_flags(&self, cmd: &mut Tool) -> Result<(), Error> { + fn ios_watchos_flags(&self, cmd: &mut Tool) -> Result<(), Error> { enum ArchSpec { Device(&'static str), Simulator(&'static str), Catalyst(&'static str), } + enum Os { + Ios, + WatchOs, + } + impl Display for Os { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Os::Ios => f.write_str("iOS"), + Os::WatchOs => f.write_str("WatchOS"), + } + } + } + let target = self.get_target()?; + let os = if target.contains("-watchos") { + Os::WatchOs + } else { + Os::Ios + }; + let arch = target.split('-').nth(0).ok_or_else(|| { Error::new( ErrorKind::ArchitectureInvalid, - "Unknown architecture for iOS target.", + format!("Unknown architecture for {} target.", os).as_str(), ) })?; @@ -2083,6 +2213,7 @@ impl Build { } else if is_sim { match arch { "arm64" | "aarch64" => ArchSpec::Simulator("-arch arm64"), + "x86_64" => ArchSpec::Simulator("-m64"), _ => { return Err(Error::new( ErrorKind::ArchitectureInvalid, @@ -2093,49 +2224,66 @@ impl Build { } else { match arch { "arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"), + "armv7k" => ArchSpec::Device("armv7k"), "armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"), "arm64e" => ArchSpec::Device("arm64e"), "arm64" | "aarch64" => ArchSpec::Device("arm64"), + "arm64_32" => ArchSpec::Device("arm64_32"), "i386" | "i686" => ArchSpec::Simulator("-m32"), "x86_64" => ArchSpec::Simulator("-m64"), _ => { return Err(Error::new( ErrorKind::ArchitectureInvalid, - "Unknown architecture for iOS target.", + format!("Unknown architecture for {} target.", os).as_str(), )); } } }; - let min_version = - std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()); + let (sdk_prefix, sim_prefix, min_version) = match os { + Os::Ios => ( + "iphone", + "ios-", + std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()), + ), + Os::WatchOs => ( + "watch", + "watch", + std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()), + ), + }; let sdk = match arch { ArchSpec::Device(arch) => { cmd.args.push("-arch".into()); cmd.args.push(arch.into()); cmd.args - .push(format!("-miphoneos-version-min={}", min_version).into()); - "iphoneos" + .push(format!("-m{}os-version-min={}", sdk_prefix, min_version).into()); + format!("{}os", sdk_prefix) } ArchSpec::Simulator(arch) => { cmd.args.push(arch.into()); cmd.args - .push(format!("-mios-simulator-version-min={}", min_version).into()); - "iphonesimulator" + .push(format!("-m{}simulator-version-min={}", sim_prefix, min_version).into()); + format!("{}simulator", sdk_prefix) } - ArchSpec::Catalyst(_) => "macosx", + ArchSpec::Catalyst(_) => "macosx".to_owned(), + }; + + self.print(&format!("Detecting {} SDK path for {}", os, sdk)); + let sdk_path = if let Some(sdkroot) = env::var_os("SDKROOT") { + sdkroot + } else { + self.apple_sdk_root(sdk.as_str())? }; - self.print(&format!("Detecting iOS SDK path for {}", sdk)); - let sdk_path = self.apple_sdk_root(sdk)?; cmd.args.push("-isysroot".into()); cmd.args.push(sdk_path); cmd.args.push("-fembed-bitcode".into()); /* * TODO we probably ultimately want the -fembed-bitcode-marker flag * but can't have it now because of an issue in LLVM: - * https://github.com/alexcrichton/cc-rs/issues/301 + * https://github.com/rust-lang/cc-rs/issues/301 * https://github.com/rust-lang/rust/pull/48896#comment-372192660 */ /* @@ -2226,10 +2374,13 @@ impl Build { if target.contains("msvc") { msvc.to_string() } else { - format!("{}.exe", gnu) + let cc = if target.contains("llvm") { clang } else { gnu }; + format!("{}.exe", cc) } } else if target.contains("apple-ios") { clang.to_string() + } else if target.contains("apple-watchos") { + clang.to_string() } else if target.contains("android") { autodetect_android_compiler(&target, &host, gnu, clang) } else if target.contains("cloudabi") { @@ -2252,7 +2403,10 @@ impl Build { } else if self.get_host()? != target { let prefix = self.prefix_for_target(&target); match prefix { - Some(prefix) => format!("{}-{}", prefix, gnu), + Some(prefix) => { + let cc = if target.contains("llvm") { clang } else { gnu }; + format!("{}-{}", prefix, cc) + } None => default.to_string(), } } else { @@ -2511,10 +2665,29 @@ impl Build { "emar".to_string() } else if target.contains("msvc") { - match windows_registry::find(&target, "lib.exe") { - Some(t) => return Ok((t, "lib.exe".to_string())), - None => "lib.exe".to_string(), + let compiler = self.get_base_compiler()?; + let mut lib = String::new(); + if compiler.family == (ToolFamily::Msvc { clang_cl: true }) { + // See if there is 'llvm-lib' next to 'clang-cl' + // Another possibility could be to see if there is 'clang' + // next to 'clang-cl' and use 'search_programs()' to locate + // 'llvm-lib'. This is because 'clang-cl' doesn't support + // the -print-search-dirs option. + if let Some(mut cmd) = which(&compiler.path) { + cmd.pop(); + cmd.push("llvm-lib.exe"); + if let Some(llvm_lib) = which(&cmd) { + lib = llvm_lib.to_str().unwrap().to_owned(); + } + } } + if lib.is_empty() { + lib = match windows_registry::find(&target, "lib.exe") { + Some(t) => return Ok((t, "lib.exe".to_string())), + None => "lib.exe".to_string(), + } + } + lib } else if target.contains("illumos") { // The default 'ar' on illumos uses a non-standard flags, // but the OS comes bundled with a GNU-compatible variant. @@ -2524,12 +2697,20 @@ impl Build { } else if self.get_host()? != target { match self.prefix_for_target(&target) { Some(p) => { - let target_ar = format!("{}-ar", p); - if Command::new(&target_ar).output().is_ok() { - target_ar - } else { - default_ar + // GCC uses $target-gcc-ar, whereas binutils uses $target-ar -- try both. + // Prefer -ar if it exists, as builds of `-gcc-ar` have been observed to be + // outright broken (such as when targetting freebsd with `--disable-lto` + // toolchain where the archiver attempts to load the LTO plugin anyway but + // fails to find one). + let mut ar = default_ar; + for &infix in &["", "-gcc"] { + let target_ar = format!("{}{}-ar", p, infix); + if Command::new(&target_ar).output().is_ok() { + ar = target_ar; + break; + } } + ar } None => default_ar, } @@ -2540,13 +2721,25 @@ impl Build { } fn prefix_for_target(&self, target: &str) -> Option { + // Put aside RUSTC_LINKER's prefix to be used as last resort + let rustc_linker = self.getenv("RUSTC_LINKER").unwrap_or("".to_string()); + // let linker_prefix = rustc_linker.strip_suffix("-gcc"); // >=1.45.0 + let linker_prefix = if rustc_linker.len() > 4 { + let (prefix, suffix) = rustc_linker.split_at(rustc_linker.len() - 4); + if suffix == "-gcc" { + Some(prefix) + } else { + None + } + } else { + None + }; // CROSS_COMPILE is of the form: "arm-linux-gnueabi-" let cc_env = self.getenv("CROSS_COMPILE"); - let cross_compile = cc_env - .as_ref() - .map(|s| s.trim_right_matches('-').to_owned()); + let cross_compile = cc_env.as_ref().map(|s| s.trim_end_matches('-').to_owned()); cross_compile.or(match &target[..] { - "aarch64-pc-windows-gnu" => Some("aarch64-w64-mingw32"), + // Note: there is no `aarch64-pc-windows-gnu` target, only `-gnullvm` + "aarch64-pc-windows-gnullvm" => Some("aarch64-w64-mingw32"), "aarch64-uwp-windows-gnu" => Some("aarch64-w64-mingw32"), "aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"), "aarch64-unknown-linux-musl" => Some("aarch64-linux-musl"), @@ -2606,6 +2799,11 @@ impl Build { "riscv64-unknown-elf", "riscv-none-embed", ]), + "riscv32imac-unknown-xous-elf" => self.find_working_gnu_prefix(&[ + "riscv32-unknown-elf", + "riscv64-unknown-elf", + "riscv-none-embed", + ]), "riscv32imc-unknown-none-elf" => self.find_working_gnu_prefix(&[ "riscv32-unknown-elf", "riscv64-unknown-elf", @@ -2644,6 +2842,7 @@ impl Build { "thumbv8m.main-none-eabi" => Some("arm-none-eabi"), "thumbv8m.main-none-eabihf" => Some("arm-none-eabi"), "x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"), + "x86_64-pc-windows-gnullvm" => Some("x86_64-w64-mingw32"), "x86_64-uwp-windows-gnu" => Some("x86_64-w64-mingw32"), "x86_64-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"), "x86_64-unknown-linux-gnu" => self.find_working_gnu_prefix(&[ @@ -2651,7 +2850,7 @@ impl Build { ]), // explicit None if not found, so caller knows to fall back "x86_64-unknown-linux-musl" => Some("musl"), "x86_64-unknown-netbsd" => Some("x86_64--netbsd"), - _ => None, + _ => linker_prefix, } .map(|x| x.to_owned())) } @@ -2716,6 +2915,25 @@ impl Build { }) } + fn get_dwarf_version(&self) -> Option { + // Tentatively matches the DWARF version defaults as of rustc 1.62. + let target = self.get_target().ok()?; + if target.contains("android") + || target.contains("apple") + || target.contains("dragonfly") + || target.contains("freebsd") + || target.contains("netbsd") + || target.contains("openbsd") + || target.contains("windows-gnu") + { + Some(2) + } else if target.contains("linux") { + Some(4) + } else { + None + } + } + fn get_force_frame_pointer(&self) -> bool { self.force_frame_pointer.unwrap_or_else(|| self.get_debug()) } @@ -2733,10 +2951,27 @@ impl Build { } fn getenv(&self, v: &str) -> Option { + // Returns true for environment variables cargo sets for build scripts: + // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts + // + // This handles more of the vars than we actually use (it tries to check + // complete-ish set), just to avoid needing maintenance if/when new + // calls to `getenv`/`getenv_unwrap` are added. + fn provided_by_cargo(envvar: &str) -> bool { + match envvar { + v if v.starts_with("CARGO") || v.starts_with("RUSTC") => true, + "HOST" | "TARGET" | "RUSTDOC" | "OUT_DIR" | "OPT_LEVEL" | "DEBUG" | "PROFILE" + | "NUM_JOBS" | "RUSTFLAGS" => true, + _ => false, + } + } let mut cache = self.env_cache.lock().unwrap(); if let Some(val) = cache.get(v) { return val.clone(); } + if self.emit_rerun_if_env_changed && !provided_by_cargo(v) { + self.print(&format!("cargo:rerun-if-env-changed={}", v)); + } let r = env::var(v).ok(); self.print(&format!("{} = {:?}", v, r)); cache.insert(v.to_string(), r.clone()); @@ -2806,7 +3041,7 @@ impl Build { Err(_) => { return Err(Error::new( ErrorKind::IOError, - "Unable to determine iOS SDK path.", + "Unable to determine Apple SDK path.", )); } }; @@ -2814,6 +3049,13 @@ impl Build { cache.insert(sdk.into(), ret.clone()); Ok(ret) } + + fn cuda_file_count(&self) -> usize { + self.files + .iter() + .filter(|file| file.extension() == Some(OsStr::new("cu"))) + .count() + } } impl Default for Build { @@ -3123,7 +3365,7 @@ fn spawn(cmd: &mut Command, program: &str) -> Result<(Child, JoinHandle<()>), Er } Err(ref e) if e.kind() == io::ErrorKind::NotFound => { let extra = if cfg!(windows) { - " (see https://github.com/alexcrichton/cc-rs#compile-time-requirements \ + " (see https://github.com/rust-lang/cc-rs#compile-time-requirements \ for help)" } else { "" @@ -3299,3 +3541,28 @@ fn which(tool: &Path) -> Option { return if check_exe(&mut exe) { Some(exe) } else { None }; }) } + +#[derive(Clone, Copy, PartialEq)] +enum AsmFileExt { + /// `.asm` files. On MSVC targets, we assume these should be passed to MASM + /// (`ml{,64}.exe`). + DotAsm, + /// `.s` or `.S` files, which do not have the special handling on MSVC targets. + DotS, +} + +impl AsmFileExt { + fn from_path(file: &Path) -> Option { + if let Some(ext) = file.extension() { + if let Some(ext) = ext.to_str() { + let ext = ext.to_lowercase(); + match &*ext { + "asm" => return Some(AsmFileExt::DotAsm), + "s" => return Some(AsmFileExt::DotS), + _ => return None, + } + } + } + None + } +} diff --git a/third_party/rust/cc/src/registry.rs b/third_party/rust/cc/src/registry.rs index 2ac2fa63ba8c..cae32219c7fb 100644 --- a/third_party/rust/cc/src/registry.rs +++ b/third_party/rust/cc/src/registry.rs @@ -3,8 +3,8 @@ // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license -// , at your +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// , at your // option. This file may not be copied, modified, or distributed // except according to those terms. @@ -14,7 +14,8 @@ use std::ops::RangeFrom; use std::os::raw; use std::os::windows::prelude::*; -pub struct RegistryKey(Repr); +/// Must never be `HKEY_PERFORMANCE_DATA`. +pub(crate) struct RegistryKey(Repr); type HKEY = *mut u8; type DWORD = u32; @@ -29,7 +30,8 @@ type REGSAM = u32; const ERROR_SUCCESS: DWORD = 0; const ERROR_NO_MORE_ITEMS: DWORD = 259; -const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY; +// Sign-extend into 64 bits if needed. +const HKEY_LOCAL_MACHINE: HKEY = 0x80000002u32 as i32 as isize as HKEY; const REG_SZ: DWORD = 1; const KEY_READ: DWORD = 0x20019; const KEY_WOW64_32KEY: DWORD = 0x200; @@ -66,8 +68,11 @@ extern "system" { struct OwnedKey(HKEY); +/// Note: must not encode `HKEY_PERFORMANCE_DATA` or one of its subkeys. enum Repr { - Const(HKEY), + /// `HKEY_LOCAL_MACHINE`. + LocalMachine, + /// A subkey of `HKEY_LOCAL_MACHINE`. Owned(OwnedKey), } @@ -79,16 +84,17 @@ pub struct Iter<'a> { unsafe impl Sync for Repr {} unsafe impl Send for Repr {} -pub static LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE)); +pub(crate) const LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::LocalMachine); impl RegistryKey { fn raw(&self) -> HKEY { match self.0 { - Repr::Const(val) => val, + Repr::LocalMachine => HKEY_LOCAL_MACHINE, Repr::Owned(ref val) => val.0, } } + /// Open a sub-key of `self`. pub fn open(&self, key: &OsStr) -> io::Result { let key = key.encode_wide().chain(Some(0)).collect::>(); let mut ret = 0 as *mut _; @@ -140,9 +146,13 @@ impl RegistryKey { } // The length here is the length in bytes, but we're using wide - // characters so we need to be sure to halve it for the capacity + // characters so we need to be sure to halve it for the length // passed in. - let mut v = Vec::with_capacity(len as usize / 2); + assert!(len % 2 == 0, "impossible wide string size: {} bytes", len); + let vlen = len as usize / 2; + // Defensively initialized, see comment about + // `HKEY_PERFORMANCE_DATA` below. + let mut v = vec![0u16; vlen]; let err = RegQueryValueExW( self.raw(), name.as_ptr(), @@ -151,17 +161,34 @@ impl RegistryKey { v.as_mut_ptr() as *mut _, &mut len, ); + // We don't check for `ERROR_MORE_DATA` (which would if the value + // grew between the first and second call to `RegQueryValueExW`), + // both because it's extremely unlikely, and this is a bit more + // defensive more defensive against weird types of registry keys. if err != ERROR_SUCCESS as LONG { return Err(io::Error::from_raw_os_error(err as i32)); } - v.set_len(len as usize / 2); - + // The length is allowed to change, but should still be even, as + // well as smaller. + assert!(len % 2 == 0, "impossible wide string size: {} bytes", len); + // If the length grew but returned a success code, it *probably* + // indicates we're `HKEY_PERFORMANCE_DATA` or a subkey(?). We + // consider this UB, since those keys write "undefined" or + // "unpredictable" values to len, and need to use a completely + // different loop structure. This should be impossible (and enforce + // it in the API to the best of our ability), but to mitigate the + // damage we do some smoke-checks on the len, and ensure `v` has + // been fully initialized (rather than trusting the result of + // `RegQueryValueExW`). + let actual_len = len as usize / 2; + assert!(actual_len <= v.len()); + v.truncate(actual_len); // Some registry keys may have a terminating nul character, but // we're not interested in that, so chop it off if it's there. - if v[v.len() - 1] == 0 { + if !v.is_empty() && v[v.len() - 1] == 0 { v.pop(); } - Ok(OsString::from_wide(&v)) + return Ok(OsString::from_wide(&v)); } } } diff --git a/third_party/rust/cc/src/setup_config.rs b/third_party/rust/cc/src/setup_config.rs index bc2b1c2d30a3..030051ca6963 100644 --- a/third_party/rust/cc/src/setup_config.rs +++ b/third_party/rust/cc/src/setup_config.rs @@ -1,7 +1,7 @@ // Copyright © 2017 winapi-rs developers // Licensed under the Apache License, Version 2.0 -// or the MIT license -// , at your option. +// or the MIT license +// , at your option. // All files in the project carrying such notice may not be copied, modified, or distributed // except according to those terms. diff --git a/third_party/rust/cc/src/winapi.rs b/third_party/rust/cc/src/winapi.rs index c416325b5241..8e04ce9cbd91 100644 --- a/third_party/rust/cc/src/winapi.rs +++ b/third_party/rust/cc/src/winapi.rs @@ -1,7 +1,7 @@ // Copyright © 2015-2017 winapi-rs developers // Licensed under the Apache License, Version 2.0 -// or the MIT license -// , at your option. +// or the MIT license +// , at your option. // All files in the project carrying such notice may not be copied, modified, or distributed // except according to those terms. diff --git a/third_party/rust/cc/src/windows_registry.rs b/third_party/rust/cc/src/windows_registry.rs index 549082b30af2..276688b03f50 100644 --- a/third_party/rust/cc/src/windows_registry.rs +++ b/third_party/rust/cc/src/windows_registry.rs @@ -3,8 +3,8 @@ // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license -// , at your +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// , at your // option. This file may not be copied, modified, or distributed // except according to those terms. @@ -393,7 +393,7 @@ mod impl_ { // according to Microsoft. To help head off potential regressions though, // we keep the registry method as a fallback option. // - // [more reliable]: https://github.com/alexcrichton/cc-rs/pull/331 + // [more reliable]: https://github.com/rust-lang/cc-rs/pull/331 fn find_tool_in_vs15_path(tool: &str, target: &str) -> Option { let mut path = match vs15plus_instances(target) { Some(instances) => instances @@ -431,7 +431,7 @@ mod impl_ { target: &str, instance_path: &PathBuf, ) -> Option { - let (bin_path, host_dylib_path, lib_path, include_path) = + let (root_path, bin_path, host_dylib_path, lib_path, include_path) = vs15plus_vc_paths(target, instance_path)?; let tool_path = bin_path.join(tool); if !tool_path.exists() { @@ -444,7 +444,7 @@ mod impl_ { tool.libs.push(lib_path); tool.include.push(include_path); - if let Some((atl_lib_path, atl_include_path)) = atl_paths(target, &bin_path) { + if let Some((atl_lib_path, atl_include_path)) = atl_paths(target, &root_path) { tool.libs.push(atl_lib_path); tool.include.push(atl_include_path); } @@ -457,7 +457,7 @@ mod impl_ { fn vs15plus_vc_paths( target: &str, instance_path: &PathBuf, - ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf)> { + ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf, PathBuf)> { let version_path = instance_path.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"); let mut version_file = File::open(version_path).ok()?; @@ -490,7 +490,7 @@ mod impl_ { .join(&host.to_lowercase()); let lib_path = path.join("lib").join(&target); let include_path = path.join("include"); - Some((bin_path, host_dylib_path, lib_path, include_path)) + Some((path, bin_path, host_dylib_path, lib_path, include_path)) } fn atl_paths(target: &str, path: &Path) -> Option<(PathBuf, PathBuf)> { diff --git a/third_party/rust/cc/tests/test.rs b/third_party/rust/cc/tests/test.rs index 3c9b4dc4983c..161abd8ab7e1 100644 --- a/third_party/rust/cc/tests/test.rs +++ b/third_party/rust/cc/tests/test.rs @@ -20,7 +20,7 @@ fn gnu_smoke() { test.cmd(0) .must_have("-O2") .must_have("foo.c") - .must_not_have("-g") + .must_not_have("-gdwarf-4") .must_have("-c") .must_have("-ffunction-sections") .must_have("-fdata-sections"); @@ -52,11 +52,26 @@ fn gnu_opt_level_s() { .must_not_have("-Oz"); } +#[test] +fn gnu_debug() { + let test = Test::gnu(); + test.gcc().debug(true).file("foo.c").compile("foo"); + test.cmd(0).must_have("-gdwarf-4"); + + let test = Test::gnu(); + test.gcc() + .target("x86_64-apple-darwin") + .debug(true) + .file("foo.c") + .compile("foo"); + test.cmd(0).must_have("-gdwarf-2"); +} + #[test] fn gnu_debug_fp_auto() { let test = Test::gnu(); test.gcc().debug(true).file("foo.c").compile("foo"); - test.cmd(0).must_have("-g"); + test.cmd(0).must_have("-gdwarf-4"); test.cmd(0).must_have("-fno-omit-frame-pointer"); } @@ -64,7 +79,7 @@ fn gnu_debug_fp_auto() { fn gnu_debug_fp() { let test = Test::gnu(); test.gcc().debug(true).file("foo.c").compile("foo"); - test.cmd(0).must_have("-g"); + test.cmd(0).must_have("-gdwarf-4"); test.cmd(0).must_have("-fno-omit-frame-pointer"); } @@ -78,7 +93,7 @@ fn gnu_debug_nofp() { .force_frame_pointer(false) .file("foo.c") .compile("foo"); - test.cmd(0).must_have("-g"); + test.cmd(0).must_have("-gdwarf-4"); test.cmd(0).must_not_have("-fno-omit-frame-pointer"); let test = Test::gnu(); @@ -87,7 +102,7 @@ fn gnu_debug_nofp() { .debug(true) .file("foo.c") .compile("foo"); - test.cmd(0).must_have("-g"); + test.cmd(0).must_have("-gdwarf-4"); test.cmd(0).must_not_have("-fno-omit-frame-pointer"); } @@ -343,6 +358,14 @@ fn gnu_static() { test.cmd(0).must_have("-static").must_not_have("-shared"); } +#[test] +fn gnu_no_dash_dash() { + let test = Test::gnu(); + test.gcc().file("foo.c").compile("foo"); + + test.cmd(0).must_not_have("--"); +} + #[test] fn msvc_smoke() { reset_env(); @@ -411,3 +434,28 @@ fn msvc_no_static_crt() { test.cmd(0).must_have("-MD"); } + +#[test] +fn msvc_no_dash_dash() { + let test = Test::msvc(); + test.gcc().file("foo.c").compile("foo"); + + test.cmd(0).must_not_have("--"); +} + +// Disable this test with the parallel feature because the execution +// order is not deterministic. +#[cfg(not(feature = "parallel"))] +#[test] +fn asm_flags() { + let test = Test::gnu(); + test.gcc() + .file("foo.c") + .file("x86_64.asm") + .file("x86_64.S") + .asm_flag("--abc") + .compile("foo"); + test.cmd(0).must_not_have("--abc"); + test.cmd(1).must_have("--abc"); + test.cmd(2).must_have("--abc"); +}