Skip to content

Commit

Permalink
Fall back to rustc's default value for crt-static/static_flag
Browse files Browse the repository at this point in the history
We do this by storing the default target features in `TargetInfo`.
  • Loading branch information
madsmtm committed Nov 4, 2024
1 parent 7414fde commit 54c1a4c
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 20 deletions.
10 changes: 10 additions & 0 deletions dev-tools/gen-target-info/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
let os = spec.os.as_deref().unwrap_or("none");
let env = spec.env.as_deref().unwrap_or("");
let abi = spec.abi.as_deref().unwrap_or("");
let features = spec.cfgs.target_features.join(",");

let unversioned_llvm_target = if spec.llvm_target.contains("apple") {
// Remove deployment target information from LLVM target triples (we
Expand Down Expand Up @@ -84,6 +85,15 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
f,
" unversioned_llvm_target: {unversioned_llvm_target:?},"
)?;
// NOTE: Features are generated from nightly versions, which will
// result in unstable values being output here as well. That is
// probably desirable since:
// 1. They're only used when `cc` is used outside a build script, and
// then we can't do feature detection, so we have to pick either
// the stable or the nightly representation.
// 2. The nightly representation is much more feature-ful, and `cc`'s
// conversion is going to be best-effort anyhow.
writeln!(f, " features: {features:?},")?;
writeln!(f, " }},")?;
writeln!(f, " ),")?;
}
Expand Down
3 changes: 1 addition & 2 deletions dev-tools/gen-target-info/src/target_specs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ pub struct RustcTargetSpecs(
);

/// Potentially useful values from:
/// https://doc.rust-lang.org/reference/conditional-compilation.html
///
/// <https://doc.rust-lang.org/reference/conditional-compilation.html>
/// That are not directly / easily exposed in `TargetSpec`.
#[derive(Debug, Default)]
pub struct Cfgs {
Expand Down
31 changes: 13 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,10 @@ impl Build {
/// When enabled on systems that support dynamic linking, this prevents
/// linking with the shared libraries.
///
/// If not specified, this falls back to:
/// - `-Ctarget-features=+crt-static` when compiling in a build script.
/// - A target-specific default.
///
/// # Example
///
/// ```no_run
Expand Down Expand Up @@ -1301,6 +1305,9 @@ impl Build {
/// 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.
///
/// If not specified, this falls back to `-Ctarget-features=+crt-static`
/// when compiling in a build script.
pub fn static_crt(&mut self, static_crt: bool) -> &mut Build {
self.static_crt = Some(static_crt);
self
Expand Down Expand Up @@ -1944,18 +1951,10 @@ impl Build {
ToolFamily::Msvc { .. } => {
cmd.push_cc_arg("-nologo".into());

let crt_flag = match self.static_crt {
Some(true) => "-MT",
Some(false) => "-MD",
None => {
let features = self.getenv("CARGO_CFG_TARGET_FEATURE");
let features = features.as_deref().unwrap_or_default();
if features.to_string_lossy().contains("crt-static") {
"-MT"
} else {
"-MD"
}
}
let crt_flag = if self.static_crt.unwrap_or_else(|| target.crt_static()) {
"-MT"
} else {
"-MD"
};
cmd.push_cc_arg(crt_flag.into());

Expand Down Expand Up @@ -2142,12 +2141,8 @@ impl Build {
cmd.args.push("-finput-charset=utf-8".into());
}

if self.static_flag.is_none() {
let features = self.getenv("CARGO_CFG_TARGET_FEATURE");
let features = features.as_deref().unwrap_or_default();
if features.to_string_lossy().contains("crt-static") {
cmd.args.push("-static".into());
}
if self.static_flag.is_none() && target.crt_static() {
cmd.args.push("-static".into());
}

// armv7 targets get to use armv7 instructions
Expand Down
17 changes: 17 additions & 0 deletions src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ pub(crate) struct TargetInfo<'a> {
///
/// This is the same as the value of `cfg!(target_abi)`.
pub abi: &'a str,
/// The set of target features, separated by commas.
/// See <https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute>
///
/// This is the same as the value of `CARGO_CFG_TARGET_FEATURE`, and
/// can be overwritten by the user with `-Ctarget-feature=...`.
///
/// This means it also includes the special feature `crt-static`.
/// NOTE: The default value is not available to build scripts, see:
/// <https://github.com/rust-lang/cargo/issues/14778>
features: &'a str,
/// The unversioned LLVM/Clang target triple.
unversioned_llvm_target: &'a str,
}
Expand All @@ -66,6 +76,13 @@ impl FromStr for TargetInfo<'_> {
}
}

impl TargetInfo<'_> {
/// See <https://doc.rust-lang.org/reference/linkage.html#static-and-dynamic-c-runtimes>
pub(crate) fn crt_static(&self) -> bool {
self.features.contains("crt-static")
}
}

#[cfg(test)]
mod tests {
use std::str::FromStr;
Expand Down
Loading

0 comments on commit 54c1a4c

Please sign in to comment.