Skip to content

Commit 54c1a4c

Browse files
committed
Fall back to rustc's default value for crt-static/static_flag
We do this by storing the default target features in `TargetInfo`.
1 parent 7414fde commit 54c1a4c

File tree

6 files changed

+341
-20
lines changed

6 files changed

+341
-20
lines changed

dev-tools/gen-target-info/src/main.rs

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
2525
let os = spec.os.as_deref().unwrap_or("none");
2626
let env = spec.env.as_deref().unwrap_or("");
2727
let abi = spec.abi.as_deref().unwrap_or("");
28+
let features = spec.cfgs.target_features.join(",");
2829

2930
let unversioned_llvm_target = if spec.llvm_target.contains("apple") {
3031
// Remove deployment target information from LLVM target triples (we
@@ -84,6 +85,15 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
8485
f,
8586
" unversioned_llvm_target: {unversioned_llvm_target:?},"
8687
)?;
88+
// NOTE: Features are generated from nightly versions, which will
89+
// result in unstable values being output here as well. That is
90+
// probably desirable since:
91+
// 1. They're only used when `cc` is used outside a build script, and
92+
// then we can't do feature detection, so we have to pick either
93+
// the stable or the nightly representation.
94+
// 2. The nightly representation is much more feature-ful, and `cc`'s
95+
// conversion is going to be best-effort anyhow.
96+
writeln!(f, " features: {features:?},")?;
8797
writeln!(f, " }},")?;
8898
writeln!(f, " ),")?;
8999
}

dev-tools/gen-target-info/src/target_specs.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ pub struct RustcTargetSpecs(
3737
);
3838

3939
/// Potentially useful values from:
40-
/// https://doc.rust-lang.org/reference/conditional-compilation.html
41-
///
40+
/// <https://doc.rust-lang.org/reference/conditional-compilation.html>
4241
/// That are not directly / easily exposed in `TargetSpec`.
4342
#[derive(Debug, Default)]
4443
pub struct Cfgs {

src/lib.rs

+13-18
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,10 @@ impl Build {
793793
/// When enabled on systems that support dynamic linking, this prevents
794794
/// linking with the shared libraries.
795795
///
796+
/// If not specified, this falls back to:
797+
/// - `-Ctarget-features=+crt-static` when compiling in a build script.
798+
/// - A target-specific default.
799+
///
796800
/// # Example
797801
///
798802
/// ```no_run
@@ -1301,6 +1305,9 @@ impl Build {
13011305
/// Configures whether the /MT flag or the /MD flag will be passed to msvc build tools.
13021306
///
13031307
/// This option defaults to `false`, and affect only msvc targets.
1308+
///
1309+
/// If not specified, this falls back to `-Ctarget-features=+crt-static`
1310+
/// when compiling in a build script.
13041311
pub fn static_crt(&mut self, static_crt: bool) -> &mut Build {
13051312
self.static_crt = Some(static_crt);
13061313
self
@@ -1944,18 +1951,10 @@ impl Build {
19441951
ToolFamily::Msvc { .. } => {
19451952
cmd.push_cc_arg("-nologo".into());
19461953

1947-
let crt_flag = match self.static_crt {
1948-
Some(true) => "-MT",
1949-
Some(false) => "-MD",
1950-
None => {
1951-
let features = self.getenv("CARGO_CFG_TARGET_FEATURE");
1952-
let features = features.as_deref().unwrap_or_default();
1953-
if features.to_string_lossy().contains("crt-static") {
1954-
"-MT"
1955-
} else {
1956-
"-MD"
1957-
}
1958-
}
1954+
let crt_flag = if self.static_crt.unwrap_or_else(|| target.crt_static()) {
1955+
"-MT"
1956+
} else {
1957+
"-MD"
19591958
};
19601959
cmd.push_cc_arg(crt_flag.into());
19611960

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

2145-
if self.static_flag.is_none() {
2146-
let features = self.getenv("CARGO_CFG_TARGET_FEATURE");
2147-
let features = features.as_deref().unwrap_or_default();
2148-
if features.to_string_lossy().contains("crt-static") {
2149-
cmd.args.push("-static".into());
2150-
}
2144+
if self.static_flag.is_none() && target.crt_static() {
2145+
cmd.args.push("-static".into());
21512146
}
21522147

21532148
// armv7 targets get to use armv7 instructions

src/target.rs

+17
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ pub(crate) struct TargetInfo<'a> {
4343
///
4444
/// This is the same as the value of `cfg!(target_abi)`.
4545
pub abi: &'a str,
46+
/// The set of target features, separated by commas.
47+
/// See <https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute>
48+
///
49+
/// This is the same as the value of `CARGO_CFG_TARGET_FEATURE`, and
50+
/// can be overwritten by the user with `-Ctarget-feature=...`.
51+
///
52+
/// This means it also includes the special feature `crt-static`.
53+
/// NOTE: The default value is not available to build scripts, see:
54+
/// <https://github.com/rust-lang/cargo/issues/14778>
55+
features: &'a str,
4656
/// The unversioned LLVM/Clang target triple.
4757
unversioned_llvm_target: &'a str,
4858
}
@@ -66,6 +76,13 @@ impl FromStr for TargetInfo<'_> {
6676
}
6777
}
6878

79+
impl TargetInfo<'_> {
80+
/// See <https://doc.rust-lang.org/reference/linkage.html#static-and-dynamic-c-runtimes>
81+
pub(crate) fn crt_static(&self) -> bool {
82+
self.features.contains("crt-static")
83+
}
84+
}
85+
6986
#[cfg(test)]
7087
mod tests {
7188
use std::str::FromStr;

0 commit comments

Comments
 (0)