summaryrefslogtreecommitdiffstats
path: root/vendor/cc/src/lib.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
commit5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch)
tree35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /vendor/cc/src/lib.rs
parentAdding debian version 1.66.0+dfsg1-1. (diff)
downloadrustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz
rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/cc/src/lib.rs')
-rw-r--r--vendor/cc/src/lib.rs217
1 files changed, 183 insertions, 34 deletions
diff --git a/vendor/cc/src/lib.rs b/vendor/cc/src/lib.rs
index e3a2b98b0..a89e35318 100644
--- a/vendor/cc/src/lib.rs
+++ b/vendor/cc/src/lib.rs
@@ -59,7 +59,7 @@
use std::collections::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::io::{self, BufRead, BufReader, Read, Write};
use std::path::{Component, Path, PathBuf};
@@ -114,6 +114,7 @@ pub struct Build {
compiler: Option<PathBuf>,
archiver: Option<PathBuf>,
cargo_metadata: bool,
+ link_lib_modifiers: Vec<String>,
pic: Option<bool>,
use_plt: Option<bool>,
static_crt: Option<bool>,
@@ -124,6 +125,7 @@ pub struct Build {
extra_warnings: Option<bool>,
env_cache: Arc<Mutex<HashMap<String, Option<String>>>>,
apple_sdk_root_cache: Arc<Mutex<HashMap<String, OsString>>>,
+ emit_rerun_if_env_changed: bool,
}
/// Represents the types of errors that may occur while using cc-rs.
@@ -168,7 +170,7 @@ impl From<io::Error> 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)
}
}
@@ -312,6 +314,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 +323,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,
}
}
@@ -475,6 +479,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 +899,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 +940,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.
@@ -1014,7 +1043,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.
@@ -1311,6 +1345,13 @@ impl Build {
if self.cuda && self.files.len() > 1 {
cmd.arg("--device-c");
}
+ 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 +1563,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());
}
@@ -1574,7 +1615,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 +1631,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(),
@@ -1849,8 +1904,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 +1961,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));
@@ -2043,18 +2106,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 +2165,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 +2176,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 +2326,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 +2355,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 {
@@ -2524,12 +2630,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 +2654,25 @@ impl Build {
}
fn prefix_for_target(&self, target: &str) -> Option<String> {
+ // 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 +2732,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 +2775,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 +2783,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()))
}
@@ -2733,10 +2865,27 @@ impl Build {
}
fn getenv(&self, v: &str) -> Option<String> {
+ // 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 +2955,7 @@ impl Build {
Err(_) => {
return Err(Error::new(
ErrorKind::IOError,
- "Unable to determine iOS SDK path.",
+ "Unable to determine Apple SDK path.",
));
}
};
@@ -3123,7 +3272,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 {
""