Skip to content

Commit a8b54d6

Browse files
authored
Rollup merge of rust-lang#133092 - madsmtm:bootstrap-deployment-target, r=Mark-Simulacrum
Always set the deployment target when building std `cc` has [a bug/feature](rust-lang/cc-rs#1171) (I guess depending on how you look at it) where the default deployment target is taken from the SDK instead of from `rustc`. This causes `compiler-builtins` to build `compiler-rt` with the wrong deployment target on iOS. I've been meaning to change how `cc` works in this regard, but that's a lengthy process, so let's fix it in bootstrap for now. The behaviour be seen locally with `./x build library --set build.optimized-compiler-builtins=true` for various target triples, and then inspecting with `otool -l build/host/stage1/lib/rustlib/*/lib/libcompiler_builtins-*.rlib | rg 'minos|version'`. I have added a rmake test that ensures that we now have the same version everywhere. Fixes rust-lang#128419 Fixes rust-lang/compiler-builtins#650 See also rust-lang/cargo#13115 `@rustbot` label O-apple
2 parents 960f367 + ff3dab4 commit a8b54d6

File tree

7 files changed

+118
-58
lines changed

7 files changed

+118
-58
lines changed

src/bootstrap/src/core/build_steps/compile.rs

+59-3
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,63 @@ fn compiler_rt_for_profiler(builder: &Builder<'_>) -> PathBuf {
462462
/// Configure cargo to compile the standard library, adding appropriate env vars
463463
/// and such.
464464
pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
465-
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
466-
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
465+
// rustc already ensures that it builds with the minimum deployment
466+
// target, so ideally we shouldn't need to do anything here.
467+
//
468+
// However, `cc` currently defaults to a higher version for backwards
469+
// compatibility, which means that compiler-rt, which is built via
470+
// compiler-builtins' build script, gets built with a higher deployment
471+
// target. This in turn causes warnings while linking, and is generally
472+
// a compatibility hazard.
473+
//
474+
// So, at least until https://github.com/rust-lang/cc-rs/issues/1171, or
475+
// perhaps https://github.com/rust-lang/cargo/issues/13115 is resolved, we
476+
// explicitly set the deployment target environment variables to avoid
477+
// this issue.
478+
//
479+
// This place also serves as an extension point if we ever wanted to raise
480+
// rustc's default deployment target while keeping the prebuilt `std` at
481+
// a lower version, so it's kinda nice to have in any case.
482+
if target.contains("apple") && !builder.config.dry_run() {
483+
// Query rustc for the deployment target.
484+
let mut cmd = command(builder.rustc(cargo.compiler()));
485+
cmd.arg("--target").arg(target.rustc_target_arg());
486+
cmd.arg("--print=deployment-target");
487+
let output = cmd.run_capture_stdout(builder).stdout();
488+
489+
let value = output.split('=').last().unwrap().trim();
490+
491+
// FIXME: Simplify after https://github.com/rust-lang/rust/pull/133041
492+
let env_var = if target.contains("apple-darwin") {
493+
"MACOSX_DEPLOYMENT_TARGET"
494+
} else if target.contains("apple-ios") {
495+
"IPHONEOS_DEPLOYMENT_TARGET"
496+
} else if target.contains("apple-tvos") {
497+
"TVOS_DEPLOYMENT_TARGET"
498+
} else if target.contains("apple-watchos") {
499+
"WATCHOS_DEPLOYMENT_TARGET"
500+
} else if target.contains("apple-visionos") {
501+
"XROS_DEPLOYMENT_TARGET"
502+
} else {
503+
panic!("unknown target OS for apple target");
504+
};
505+
506+
// Unconditionally set the env var (if it was set in the environment
507+
// already, rustc should've picked that up).
508+
cargo.env(env_var, value);
509+
510+
// Allow CI to override the deployment target for `std` on macOS.
511+
//
512+
// This is useful because we might want the host tooling LLVM, `rustc`
513+
// and Cargo to have a different deployment target than `std` itself
514+
// (currently, these two versions are the same, but in the past, we
515+
// supported macOS 10.7 for user code and macOS 10.8 in host tooling).
516+
//
517+
// It is not necessary on the other platforms, since only macOS has
518+
// support for host tooling.
519+
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
520+
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
521+
}
467522
}
468523

469524
// Paths needed by `library/profiler_builtins/build.rs`.
@@ -1564,7 +1619,8 @@ pub fn compiler_file(
15641619
return PathBuf::new();
15651620
}
15661621
let mut cmd = command(compiler);
1567-
cmd.args(builder.cflags(target, GitRepo::Rustc, c));
1622+
cmd.args(builder.default_cflags(target, c));
1623+
cmd.args(builder.extra_cflags(target, GitRepo::Rustc, c));
15681624
cmd.arg(format!("-print-file-name={file}"));
15691625
let out = cmd.run_capture_stdout(builder).stdout();
15701626
PathBuf::from(out.trim())

src/bootstrap/src/core/build_steps/llvm.rs

+8-40
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ impl Step for Llvm {
534534
cfg.define("LLVM_VERSION_SUFFIX", suffix);
535535
}
536536

537-
configure_cmake(builder, target, &mut cfg, true, ldflags, &[]);
537+
configure_cmake(builder, target, &mut cfg, true, ldflags);
538538
configure_llvm(builder, target, &mut cfg);
539539

540540
for (key, val) in &builder.config.llvm_build_config {
@@ -623,7 +623,6 @@ fn configure_cmake(
623623
cfg: &mut cmake::Config,
624624
use_compiler_launcher: bool,
625625
mut ldflags: LdFlags,
626-
suppressed_compiler_flag_prefixes: &[&str],
627626
) {
628627
// Do not print installation messages for up-to-date files.
629628
// LLVM and LLD builds can produce a lot of those and hit CI limits on log size.
@@ -757,17 +756,8 @@ fn configure_cmake(
757756
}
758757

759758
cfg.build_arg("-j").build_arg(builder.jobs().to_string());
760-
let mut cflags: OsString = builder
761-
.cflags(target, GitRepo::Llvm, CLang::C)
762-
.into_iter()
763-
.filter(|flag| {
764-
!suppressed_compiler_flag_prefixes
765-
.iter()
766-
.any(|suppressed_prefix| flag.starts_with(suppressed_prefix))
767-
})
768-
.collect::<Vec<String>>()
769-
.join(" ")
770-
.into();
759+
let mut cflags: OsString =
760+
builder.extra_cflags(target, GitRepo::Llvm, CLang::C).join(" ").into();
771761
if let Some(ref s) = builder.config.llvm_cflags {
772762
cflags.push(" ");
773763
cflags.push(s);
@@ -777,17 +767,8 @@ fn configure_cmake(
777767
cflags.push(format!(" --target={target}"));
778768
}
779769
cfg.define("CMAKE_C_FLAGS", cflags);
780-
let mut cxxflags: OsString = builder
781-
.cflags(target, GitRepo::Llvm, CLang::Cxx)
782-
.into_iter()
783-
.filter(|flag| {
784-
!suppressed_compiler_flag_prefixes
785-
.iter()
786-
.any(|suppressed_prefix| flag.starts_with(suppressed_prefix))
787-
})
788-
.collect::<Vec<String>>()
789-
.join(" ")
790-
.into();
770+
let mut cxxflags: OsString =
771+
builder.extra_cflags(target, GitRepo::Llvm, CLang::Cxx).join(" ").into();
791772
if let Some(ref s) = builder.config.llvm_cxxflags {
792773
cxxflags.push(" ");
793774
cxxflags.push(s);
@@ -950,7 +931,7 @@ impl Step for Enzyme {
950931
// FIXME(ZuseZ4): Find a nicer way to use Enzyme Debug builds
951932
//cfg.profile("Debug");
952933
//cfg.define("CMAKE_BUILD_TYPE", "Debug");
953-
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]);
934+
configure_cmake(builder, target, &mut cfg, true, LdFlags::default());
954935

955936
// Re-use the same flags as llvm to control the level of debug information
956937
// generated for lld.
@@ -1065,7 +1046,7 @@ impl Step for Lld {
10651046
ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'");
10661047
}
10671048

1068-
configure_cmake(builder, target, &mut cfg, true, ldflags, &[]);
1049+
configure_cmake(builder, target, &mut cfg, true, ldflags);
10691050
configure_llvm(builder, target, &mut cfg);
10701051

10711052
// Re-use the same flags as llvm to control the level of debug information
@@ -1164,20 +1145,7 @@ impl Step for Sanitizers {
11641145
// Unfortunately sccache currently lacks support to build them successfully.
11651146
// Disable compiler launcher on Darwin targets to avoid potential issues.
11661147
let use_compiler_launcher = !self.target.contains("apple-darwin");
1167-
// Since v1.0.86, the cc crate adds -mmacosx-version-min to the default
1168-
// flags on MacOS. A long-standing bug in the CMake rules for compiler-rt
1169-
// causes architecture detection to be skipped when this flag is present,
1170-
// and compilation fails. https://github.com/llvm/llvm-project/issues/88780
1171-
let suppressed_compiler_flag_prefixes: &[&str] =
1172-
if self.target.contains("apple-darwin") { &["-mmacosx-version-min="] } else { &[] };
1173-
configure_cmake(
1174-
builder,
1175-
self.target,
1176-
&mut cfg,
1177-
use_compiler_launcher,
1178-
LdFlags::default(),
1179-
suppressed_compiler_flag_prefixes,
1180-
);
1148+
configure_cmake(builder, self.target, &mut cfg, use_compiler_launcher, LdFlags::default());
11811149

11821150
t!(fs::create_dir_all(&out_dir));
11831151
cfg.out_dir(out_dir);

src/bootstrap/src/core/build_steps/test.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2014,14 +2014,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
20142014
// Only pass correct values for these flags for the `run-make` suite as it
20152015
// requires that a C++ compiler was configured which isn't always the case.
20162016
if !builder.config.dry_run() && mode == "run-make" {
2017+
let mut cflags = builder.default_cflags(target, CLang::C);
2018+
cflags.extend(builder.extra_cflags(target, GitRepo::Rustc, CLang::C));
2019+
let mut cxxflags = builder.default_cflags(target, CLang::Cxx);
2020+
cxxflags.extend(builder.extra_cflags(target, GitRepo::Rustc, CLang::Cxx));
20172021
cmd.arg("--cc")
20182022
.arg(builder.cc(target))
20192023
.arg("--cxx")
20202024
.arg(builder.cxx(target).unwrap())
20212025
.arg("--cflags")
2022-
.arg(builder.cflags(target, GitRepo::Rustc, CLang::C).join(" "))
2026+
.arg(cflags.join(" "))
20232027
.arg("--cxxflags")
2024-
.arg(builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" "));
2028+
.arg(cxxflags.join(" "));
20252029
copts_passed = true;
20262030
if let Some(ar) = builder.ar(target) {
20272031
cmd.arg("--ar").arg(ar);

src/bootstrap/src/core/builder/cargo.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ impl Cargo {
122122
cargo
123123
}
124124

125+
pub fn compiler(&self) -> Compiler {
126+
self.compiler
127+
}
128+
125129
pub fn into_cmd(self) -> BootstrapCommand {
126130
self.into()
127131
}
@@ -307,7 +311,7 @@ impl Cargo {
307311
let cc = ccacheify(&builder.cc(target));
308312
self.command.env(format!("CC_{triple_underscored}"), &cc);
309313

310-
let cflags = builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
314+
let cflags = builder.extra_cflags(target, GitRepo::Rustc, CLang::C).join(" ");
311315
self.command.env(format!("CFLAGS_{triple_underscored}"), &cflags);
312316

313317
if let Some(ar) = builder.ar(target) {
@@ -319,7 +323,7 @@ impl Cargo {
319323

320324
if let Ok(cxx) = builder.cxx(target) {
321325
let cxx = ccacheify(&cxx);
322-
let cxxflags = builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
326+
let cxxflags = builder.extra_cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
323327
self.command
324328
.env(format!("CXX_{triple_underscored}"), &cxx)
325329
.env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);

src/bootstrap/src/lib.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ impl Mode {
250250
}
251251
}
252252

253+
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
253254
pub enum CLang {
254255
C,
255256
Cxx,
@@ -1187,9 +1188,9 @@ Executed at: {executed_at}"#,
11871188
self.cc.borrow()[&target].path().into()
11881189
}
11891190

1190-
/// Returns a list of flags to pass to the C compiler for the target
1191-
/// specified.
1192-
fn cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec<String> {
1191+
/// Returns C flags that `cc-rs` thinks should be enabled for the
1192+
/// specified target by default.
1193+
fn default_cflags(&self, target: TargetSelection, c: CLang) -> Vec<String> {
11931194
if self.config.dry_run() {
11941195
return Vec::new();
11951196
}
@@ -1198,14 +1199,18 @@ Executed at: {executed_at}"#,
11981199
CLang::Cxx => self.cxx.borrow()[&target].clone(),
11991200
};
12001201

1201-
// Filter out -O and /O (the optimization flags) that we picked up from
1202-
// cc-rs because the build scripts will determine that for themselves.
1203-
let mut base = base
1204-
.args()
1202+
// Filter out -O and /O (the optimization flags) that we picked up
1203+
// from cc-rs, that's up to the caller to figure out.
1204+
base.args()
12051205
.iter()
12061206
.map(|s| s.to_string_lossy().into_owned())
12071207
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
1208-
.collect::<Vec<String>>();
1208+
.collect::<Vec<String>>()
1209+
}
1210+
1211+
/// Returns extra C flags that `cc-rs` doesn't handle.
1212+
fn extra_cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec<String> {
1213+
let mut base = Vec::new();
12091214

12101215
// If we're compiling C++ on macOS then we add a flag indicating that
12111216
// we want libc++ (more filled out than libstdc++), ensuring that

src/bootstrap/src/utils/cc_detect.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ pub fn find_target(build: &Build, target: TargetSelection) {
132132
};
133133

134134
build.cc.borrow_mut().insert(target, compiler.clone());
135-
let cflags = build.cflags(target, GitRepo::Rustc, CLang::C);
135+
let mut cflags = build.default_cflags(target, CLang::C);
136+
cflags.extend(build.extra_cflags(target, GitRepo::Rustc, CLang::C));
136137

137138
// If we use llvm-libunwind, we will need a C++ compiler as well for all targets
138139
// We'll need one anyways if the target triple is also a host triple
@@ -158,7 +159,8 @@ pub fn find_target(build: &Build, target: TargetSelection) {
158159
build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
159160
build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
160161
if let Ok(cxx) = build.cxx(target) {
161-
let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
162+
let mut cxxflags = build.default_cflags(target, CLang::Cxx);
163+
cxxflags.extend(build.extra_cflags(target, GitRepo::Rustc, CLang::Cxx));
162164
build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
163165
build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
164166
}

tests/run-make/apple-deployment-target/rmake.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
88
//@ only-apple
99

10-
use run_make_support::{apple_os, cmd, run_in_tmpdir, rustc, target};
10+
use std::collections::HashSet;
11+
12+
use run_make_support::{
13+
apple_os, cmd, has_extension, path, regex, run_in_tmpdir, rustc, shallow_find_files, target,
14+
};
1115

1216
/// Run vtool to check the `minos` field in LC_BUILD_VERSION.
1317
///
@@ -156,4 +160,21 @@ fn main() {
156160
rustc().env_remove(env_var).run();
157161
minos("foo.o", default_version);
158162
});
163+
164+
// Test that all binaries in rlibs produced by `rustc` have the same version.
165+
// Regression test for https://github.com/rust-lang/rust/issues/128419.
166+
let sysroot = rustc().print("sysroot").run().stdout_utf8();
167+
let target_sysroot = path(sysroot.trim()).join("lib/rustlib").join(target()).join("lib");
168+
let rlibs = shallow_find_files(&target_sysroot, |path| has_extension(path, "rlib"));
169+
170+
let output = cmd("otool").arg("-l").args(rlibs).run().stdout_utf8();
171+
let re = regex::Regex::new(r"(minos|version) ([0-9.]*)").unwrap();
172+
let mut versions = HashSet::new();
173+
for (_, [_, version]) in re.captures_iter(&output).map(|c| c.extract()) {
174+
versions.insert(version);
175+
}
176+
// FIXME(madsmtm): See above for aarch64-apple-watchos.
177+
if versions.len() != 1 && target() != "aarch64-apple-watchos" {
178+
panic!("std rlibs contained multiple different deployment target versions: {versions:?}");
179+
}
159180
}

0 commit comments

Comments
 (0)