@@ -2194,21 +2194,34 @@ impl Build {
2194
2194
2195
2195
// Pass `--target` with the LLVM target to configure Clang for cross-compiling.
2196
2196
//
2197
- // NOTE: In the past, we passed this, along with the deployment version in here
2198
- // on Apple targets, but versioned targets were found to have poor compatibility
2199
- // with older versions of Clang, especially around comes to configuration files.
2197
+ // This is **required** for cross-compilation, as it's the only flag that
2198
+ // consistently forces Clang to change the "toolchain" that is responsible for
2199
+ // parsing target-specific flags:
2200
+ // https://github.com/rust-lang/cc-rs/issues/1388
2201
+ // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.7/clang/lib/Driver/Driver.cpp#L1359-L1360
2202
+ // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.7/clang/lib/Driver/Driver.cpp#L6347-L6532
2200
2203
//
2201
- // Instead, we specify `-arch` along with `-mmacosx-version-min=`, `-mtargetos=`
2202
- // and similar flags in `.apple_flags()`.
2204
+ // This can be confusing, because on e.g. host macOS, you can usually get by
2205
+ // with `-arch` and `-mtargetos=`. But that only works because the _default_
2206
+ // toolchain is `Darwin`, which enables parsing of darwin-specific options.
2203
2207
//
2204
- // Note that Clang errors when both `-mtargetos=` and `-target` are specified,
2205
- // so we omit this entirely on Apple targets (it's redundant when specifying
2206
- // both the `-arch` and the deployment target / OS flag) (in theory we _could_
2207
- // specify this on some of the Apple targets that use the older
2208
- // `-m*-version-min=`, but for consistency we omit it entirely).
2209
- if target. vendor != "apple" {
2210
- cmd. push_cc_arg ( format ! ( "--target={}" , target. llvm_target) . into ( ) ) ;
2211
- }
2208
+ // NOTE: In the past, we passed the deployment version in here on all Apple
2209
+ // targets, but versioned targets were found to have poor compatibility with
2210
+ // older versions of Clang, especially when it comes to configuration files:
2211
+ // https://github.com/rust-lang/cc-rs/issues/1278
2212
+ //
2213
+ // So instead, we pass the deployment target with `-m*-version-min=`, and only
2214
+ // pass it here on visionOS and Mac Catalyst where that option does not exist:
2215
+ // https://github.com/rust-lang/cc-rs/issues/1383
2216
+ let clang_target = if target. os == "visionos" || target. abi == "macabi" {
2217
+ Cow :: Owned (
2218
+ target. versioned_llvm_target ( & self . apple_deployment_target ( target) ) ,
2219
+ )
2220
+ } else {
2221
+ Cow :: Borrowed ( target. llvm_target )
2222
+ } ;
2223
+
2224
+ cmd. push_cc_arg ( format ! ( "--target={clang_target}" ) . into ( ) ) ;
2212
2225
}
2213
2226
}
2214
2227
ToolFamily :: Msvc { clang_cl } => {
@@ -2648,21 +2661,23 @@ impl Build {
2648
2661
fn apple_flags ( & self , cmd : & mut Tool ) -> Result < ( ) , Error > {
2649
2662
let target = self . get_target ( ) ?;
2650
2663
2651
- // Add `-arch` on all compilers. This is a Darwin/Apple-specific flag
2652
- // that works both on GCC and Clang.
2664
+ // This is a Darwin/Apple-specific flag that works both on GCC and Clang, but it is only
2665
+ // necessary on GCC since we specify `-target` on Clang.
2653
2666
// https://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html#:~:text=arch
2654
2667
// https://clang.llvm.org/docs/CommandGuide/clang.html#cmdoption-arch
2655
- let arch = map_darwin_target_from_rust_to_compiler_architecture ( & target) ;
2656
- cmd. args . push ( "-arch" . into ( ) ) ;
2657
- cmd. args . push ( arch. into ( ) ) ;
2668
+ if cmd. is_like_gnu ( ) {
2669
+ let arch = map_darwin_target_from_rust_to_compiler_architecture ( & target) ;
2670
+ cmd. args . push ( "-arch" . into ( ) ) ;
2671
+ cmd. args . push ( arch. into ( ) ) ;
2672
+ }
2658
2673
2659
- // Pass the deployment target via `-mmacosx-version-min=`, `-mtargetos=` and similar.
2660
- //
2661
- // It is also necessary on GCC, as it forces a compilation error if the compiler is not
2674
+ // Pass the deployment target via `-mmacosx-version-min=`, `-miphoneos-version-min=` and
2675
+ // similar. Also necessary on GCC, as it forces a compilation error if the compiler is not
2662
2676
// configured for Darwin: https://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html
2663
2677
let min_version = self . apple_deployment_target ( & target) ;
2664
- cmd. args
2665
- . push ( target. apple_version_flag ( & min_version) . into ( ) ) ;
2678
+ if let Some ( flag) = target. apple_version_flag ( & min_version) {
2679
+ cmd. args . push ( flag. into ( ) ) ;
2680
+ }
2666
2681
2667
2682
// AppleClang sometimes requires sysroot even on macOS
2668
2683
if cmd. is_xctoolchain_clang ( ) || target. os != "macos" {
0 commit comments