Skip to content

Commit

Permalink
Pass deployment target with -m*-version-min= (#1339)
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm authored Jan 31, 2025
1 parent bf4dcf7 commit 8533e8c
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 378 deletions.
19 changes: 4 additions & 15 deletions dev-tools/gen-target-info/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,9 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
let env = spec.env.as_deref().unwrap_or("");
let abi = spec.abi.as_deref().unwrap_or("");

let unversioned_llvm_target = if spec.llvm_target.contains("apple") {
// Remove deployment target information from LLVM target triples (we
// will add this in another part of CC).
//
// FIXME(madsmtm): Should become unnecessary after
// https://github.com/rust-lang/rust/pull/131037
let mut components = spec.llvm_target.split("-").collect::<Vec<_>>();

components[2] = components[2].trim_end_matches(|c: char| c.is_numeric() || c == '.');

components.join("-")
// FIXME(madsmtm): Unnecessary once we bump MSRV to Rust 1.74
let llvm_target = if spec.llvm_target == "armv7-apple-ios7.0.0" {
"armv7-apple-ios".to_string()
} else if os == "uefi" {
// Override the UEFI LLVM targets.
//
Expand Down Expand Up @@ -80,10 +72,7 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
writeln!(f, " os: {os:?},")?;
writeln!(f, " env: {env:?},")?;
writeln!(f, " abi: {abi:?},")?;
writeln!(
f,
" unversioned_llvm_target: {unversioned_llvm_target:?},"
)?;
writeln!(f, " llvm_target: {llvm_target:?},")?;
writeln!(f, " }},")?;
writeln!(f, " ),")?;
}
Expand Down
44 changes: 15 additions & 29 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2188,17 +2188,14 @@ impl Build {
}
}

// Add version information to the target.
let llvm_target = if target.vendor == "apple" {
let deployment_target = self.apple_deployment_target(target);
target.versioned_llvm_target(Some(&deployment_target))
} else {
target.versioned_llvm_target(None)
};

// Pass `--target` with the LLVM target to properly
// configure Clang even when cross-compiling.
cmd.push_cc_arg(format!("--target={llvm_target}").into());
// Pass `--target` with the LLVM target to properly configure Clang even when
// cross-compiling.
//
// We intentionally don't put the deployment version in here on Apple targets,
// and instead pass that via `-mmacosx-version-min=` and similar flags, for
// better compatibility with older versions of Clang that has poor support for
// versioned target names (especially when it comes to configuration files).
cmd.push_cc_arg(format!("--target={}", target.llvm_target).into());
}
}
ToolFamily::Msvc { clang_cl } => {
Expand All @@ -2214,8 +2211,7 @@ impl Build {
cmd.push_cc_arg("-m32".into());
cmd.push_cc_arg("-arch:IA32".into());
} else {
let llvm_target = target.versioned_llvm_target(None);
cmd.push_cc_arg(format!("--target={llvm_target}").into());
cmd.push_cc_arg(format!("--target={}", target.llvm_target).into());
}
} else if target.full_arch == "i586" {
cmd.push_cc_arg("-arch:IA32".into());
Expand Down Expand Up @@ -2645,23 +2641,13 @@ impl Build {
fn apple_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
let target = self.get_target()?;

// If the compiler is Clang, then we've already specifed the target
// information (including the deployment target) with the `--target`
// option, so we don't need to do anything further here.
//
// If the compiler is GCC, then we need to specify
// `-mmacosx-version-min` to set the deployment target, as well
// as to say that the target OS is macOS.
// Pass the deployment target via `-mmacosx-version-min=`, `-mtargetos=` and similar.
//
// NOTE: GCC does not support `-miphoneos-version-min=` etc. (because
// it does not support iOS in general), but we specify them anyhow in
// case we actually have a Clang-like compiler disguised as a GNU-like
// compiler, or in case GCC adds support for these in the future.
if !cmd.is_like_clang() {
let min_version = self.apple_deployment_target(&target);
cmd.args
.push(target.apple_version_flag(&min_version).into());
}
// It is also necessary on GCC, as it forces a compilation error if the compiler is not
// configured for Darwin: https://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html
let min_version = self.apple_deployment_target(&target);
cmd.args
.push(target.apple_version_flag(&min_version).into());

// AppleClang sometimes requires sysroot even on macOS
if cmd.is_xctoolchain_clang() || target.os != "macos" {
Expand Down
5 changes: 4 additions & 1 deletion src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ pub(crate) struct TargetInfo<'a> {
/// This is the same as the value of `cfg!(target_abi)`.
pub abi: &'a str,
/// The unversioned LLVM/Clang target triple.
unversioned_llvm_target: &'a str,
///
/// NOTE: You should never need to match on this explicitly, use the other
/// fields on [`TargetInfo`] instead.
pub llvm_target: &'a str,
}

impl FromStr for TargetInfo<'_> {
Expand Down
12 changes: 12 additions & 0 deletions src/target/apple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ impl TargetInfo<'_> {
}

pub(crate) fn apple_version_flag(&self, min_version: &str) -> String {
// There are many aliases for these, and `-mtargetos=` is preferred on Clang nowadays, but
// for compatibility with older Clang, we use the earliest supported name here.
//
// NOTE: GCC does not support `-miphoneos-version-min=` etc. (because it does not support
// iOS in general), but we specify them anyhow in case we actually have a Clang-like
// compiler disguised as a GNU-like compiler, or in case GCC adds support for these in the
// future.
//
// See also:
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mmacos-version-min
// https://clang.llvm.org/docs/AttributeReference.html#availability
// https://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html#index-mmacosx-version-min
match (self.os, self.abi) {
("macos", "") => format!("-mmacosx-version-min={min_version}"),
("ios", "") => format!("-miphoneos-version-min={min_version}"),
Expand Down
Loading

0 comments on commit 8533e8c

Please sign in to comment.