Skip to content

Commit 1a9f345

Browse files
authored
Apple: Remove redundant flags (#1256)
* Refactor Apple flags Non-functional change. * Apple: Remove redundant architecture flags The architecture is specified for Clang with the --target option, and both -arch and -m32/-m64 are passed to GCC elsewhere (should probably be changed to -march, but that's a different issue). * Don't output version flag on Clang It is redundant, the version is already specified in `-target`. * Appease clippy
1 parent d2822d9 commit 1a9f345

File tree

3 files changed

+56
-148
lines changed

3 files changed

+56
-148
lines changed

src/lib.rs

+25-137
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,6 @@ pub struct Build {
325325
enum ErrorKind {
326326
/// Error occurred while performing I/O.
327327
IOError,
328-
/// Invalid architecture supplied.
329-
ArchitectureInvalid,
330328
/// Environment variable not found, with the var in question as extra info.
331329
EnvVarNotFound,
332330
/// Error occurred while using external tools (ie: invocation of compiler).
@@ -2134,7 +2132,7 @@ impl Build {
21342132
}
21352133
}
21362134
ToolFamily::Gnu => {
2137-
if target.os == "macos" {
2135+
if target.vendor == "apple" {
21382136
let arch = map_darwin_target_from_rust_to_compiler_architecture(target);
21392137
cmd.args.push("-arch".into());
21402138
cmd.args.push(arch.into());
@@ -2532,113 +2530,38 @@ impl Build {
25322530

25332531
fn apple_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
25342532
let target = self.get_target()?;
2535-
let arch_str = target.full_arch;
25362533

2537-
let arch = if target.os == "macos" {
2538-
match arch_str {
2539-
"i686" => AppleArchSpec::Device("-m32"),
2540-
"x86_64" | "x86_64h" | "aarch64" | "arm64e" => AppleArchSpec::Device("-m64"),
2541-
_ => {
2542-
return Err(Error::new(
2543-
ErrorKind::ArchitectureInvalid,
2544-
"Unknown architecture for macOS target.",
2545-
));
2546-
}
2547-
}
2548-
} else if target.abi == "macabi" {
2549-
match arch_str {
2550-
"arm64e" => AppleArchSpec::Catalyst("arm64e"),
2551-
"arm64" | "aarch64" => AppleArchSpec::Catalyst("arm64"),
2552-
"x86_64" | "x86_64h" => AppleArchSpec::Catalyst("-m64"),
2553-
_ => {
2554-
return Err(Error::new(
2555-
ErrorKind::ArchitectureInvalid,
2556-
"Unknown architecture for iOS target.",
2557-
));
2558-
}
2559-
}
2560-
} else if target.abi == "sim" {
2561-
match arch_str {
2562-
"arm64" | "aarch64" => AppleArchSpec::Simulator("arm64"),
2563-
"i386" | "i686" => AppleArchSpec::Simulator("-m32"),
2564-
"x86_64" | "x86_64h" => AppleArchSpec::Simulator("-m64"),
2565-
_ => {
2566-
return Err(Error::new(
2567-
ErrorKind::ArchitectureInvalid,
2568-
"Unknown architecture for simulator target.",
2569-
));
2570-
}
2571-
}
2572-
} else {
2573-
match arch_str {
2574-
"arm" | "armv7" | "thumbv7" => AppleArchSpec::Device("armv7"),
2575-
"armv7k" => AppleArchSpec::Device("armv7k"),
2576-
"armv7s" | "thumbv7s" => AppleArchSpec::Device("armv7s"),
2577-
"arm64e" => AppleArchSpec::Device("arm64e"),
2578-
"arm64" | "aarch64" => AppleArchSpec::Device("arm64"),
2579-
"arm64_32" => AppleArchSpec::Device("arm64_32"),
2580-
_ => {
2581-
return Err(Error::new(
2582-
ErrorKind::ArchitectureInvalid,
2583-
format!("Unknown architecture for {:?} target.", target.os),
2584-
));
2585-
}
2586-
}
2587-
};
2588-
2589-
let sdk_details = apple_os_sdk_parts(target.os, &arch);
2590-
let min_version = self.apple_deployment_target(&target);
2591-
2592-
match arch {
2593-
AppleArchSpec::Device(_) if target.os == "macos" => {
2594-
cmd.args
2595-
.push(format!("-mmacosx-version-min={}", min_version).into());
2596-
}
2597-
AppleArchSpec::Device(arch) => {
2598-
cmd.args.push("-arch".into());
2599-
cmd.args.push(arch.into());
2600-
// `-mxros-version-min` does not exist
2601-
// https://github.com/llvm/llvm-project/issues/88271
2602-
if target.os != "visionos" {
2603-
cmd.args.push(
2604-
format!("-m{}os-version-min={}", sdk_details.sdk_prefix, min_version)
2605-
.into(),
2606-
);
2607-
}
2608-
}
2609-
AppleArchSpec::Simulator(arch) => {
2610-
if arch.starts_with('-') {
2611-
// -m32 or -m64
2612-
cmd.args.push(arch.into());
2613-
} else {
2614-
cmd.args.push("-arch".into());
2615-
cmd.args.push(arch.into());
2616-
}
2617-
if target.os != "visionos" {
2618-
cmd.args.push(
2619-
format!(
2620-
"-m{}simulator-version-min={}",
2621-
sdk_details.sim_prefix, min_version
2622-
)
2623-
.into(),
2624-
);
2625-
}
2626-
}
2627-
AppleArchSpec::Catalyst(_) => {}
2628-
};
2534+
// If the compiler is Clang, then we've already specifed the target
2535+
// information (including the deployment target) with the `--target`
2536+
// option, so we don't need to do anything further here.
2537+
//
2538+
// If the compiler is GCC, then we need to specify
2539+
// `-mmacosx-version-min` to set the deployment target, as well
2540+
// as to say that the target OS is macOS.
2541+
//
2542+
// NOTE: GCC does not support `-miphoneos-version-min=` etc. (because
2543+
// it does not support iOS in general), but we specify them anyhow in
2544+
// case we actually have a Clang-like compiler disguised as a GNU-like
2545+
// compiler, or in case GCC adds support for these in the future.
2546+
if !cmd.is_like_clang() {
2547+
let min_version = self.apple_deployment_target(&target);
2548+
cmd.args
2549+
.push(target.apple_version_flag(&min_version).into());
2550+
}
26292551

26302552
// AppleClang sometimes requires sysroot even on macOS
26312553
if cmd.is_xctoolchain_clang() || target.os != "macos" {
26322554
self.cargo_output.print_metadata(&format_args!(
26332555
"Detecting {:?} SDK path for {}",
2634-
target.os, sdk_details.sdk
2556+
target.os,
2557+
target.apple_sdk_name(),
26352558
));
2636-
let sdk_path = self.apple_sdk_root(&sdk_details.sdk)?;
2559+
let sdk_path = self.apple_sdk_root(&target)?;
26372560

26382561
cmd.args.push("-isysroot".into());
26392562
cmd.args.push(OsStr::new(&sdk_path).to_owned());
26402563

2641-
if let AppleArchSpec::Catalyst(_) = arch {
2564+
if target.abi == "macabi" {
26422565
// Mac Catalyst uses the macOS SDK, but to compile against and
26432566
// link to iOS-specific frameworks, we should have the support
26442567
// library stubs in the include and library search path.
@@ -3719,7 +3642,9 @@ impl Build {
37193642
Ok(Arc::from(OsStr::new(sdk_path.trim())))
37203643
}
37213644

3722-
fn apple_sdk_root(&self, sdk: &str) -> Result<Arc<OsStr>, Error> {
3645+
fn apple_sdk_root(&self, target: &TargetInfo) -> Result<Arc<OsStr>, Error> {
3646+
let sdk = target.apple_sdk_name();
3647+
37233648
if let Some(ret) = self
37243649
.build_cache
37253650
.apple_sdk_root_cache
@@ -3974,43 +3899,6 @@ fn fail(s: &str) -> ! {
39743899
std::process::exit(1);
39753900
}
39763901

3977-
struct AppleSdkTargetParts {
3978-
sdk_prefix: &'static str,
3979-
sim_prefix: &'static str,
3980-
sdk: Cow<'static, str>,
3981-
}
3982-
3983-
fn apple_os_sdk_parts(os: &str, arch: &AppleArchSpec) -> AppleSdkTargetParts {
3984-
let (sdk_prefix, sim_prefix) = match os {
3985-
"macos" => ("macosx", ""),
3986-
"ios" => ("iphone", "ios-"),
3987-
"watchos" => ("watch", "watch"),
3988-
"tvos" => ("appletv", "appletv"),
3989-
"visionos" => ("xr", "xr"),
3990-
os => unreachable!("unknown Apple OS {}", os),
3991-
};
3992-
let sdk = match arch {
3993-
AppleArchSpec::Device(_) if os == "macos" => Cow::Borrowed("macosx"),
3994-
AppleArchSpec::Device(_) => format!("{}os", sdk_prefix).into(),
3995-
AppleArchSpec::Simulator(_) => format!("{}simulator", sdk_prefix).into(),
3996-
AppleArchSpec::Catalyst(_) => Cow::Borrowed("macosx"),
3997-
};
3998-
3999-
AppleSdkTargetParts {
4000-
sdk_prefix,
4001-
sim_prefix,
4002-
sdk,
4003-
}
4004-
}
4005-
4006-
#[allow(dead_code)]
4007-
enum AppleArchSpec {
4008-
Device(&'static str),
4009-
Simulator(&'static str),
4010-
#[allow(dead_code)]
4011-
Catalyst(&'static str),
4012-
}
4013-
40143902
// Use by default minimum available API level
40153903
// See note about naming here
40163904
// https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/docs/BuildSystemMaintainers.md#Clang

src/target/apple.rs

+18
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,22 @@ impl TargetInfo<'_> {
1616
(os, _) => panic!("invalid Apple target OS {}", os),
1717
}
1818
}
19+
20+
pub(crate) fn apple_version_flag(&self, min_version: &str) -> String {
21+
match (self.os, self.abi) {
22+
("macos", "") => format!("-mmacosx-version-min={min_version}"),
23+
("ios", "") => format!("-miphoneos-version-min={min_version}"),
24+
("ios", "sim") => format!("-mios-simulator-version-min={min_version}"),
25+
("ios", "macabi") => format!("-mtargetos=ios{min_version}-macabi"),
26+
("tvos", "") => format!("-mappletvos-version-min={min_version}"),
27+
("tvos", "sim") => format!("-mappletvsimulator-version-min={min_version}"),
28+
("watchos", "") => format!("-mwatchos-version-min={min_version}"),
29+
("watchos", "sim") => format!("-mwatchsimulator-version-min={min_version}"),
30+
// `-mxros-version-min` does not exist
31+
// https://github.com/llvm/llvm-project/issues/88271
32+
("visionos", "") => format!("-mtargetos=xros{min_version}"),
33+
("visionos", "sim") => format!("-mtargetos=xros{min_version}-simulator"),
34+
(os, _) => panic!("invalid Apple target OS {}", os),
35+
}
36+
}
1937
}

tests/test.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ fn gnu_aarch64_none_no_pic() {
274274
for target in &["aarch64-unknown-none-softfloat", "aarch64-unknown-none"] {
275275
let test = Test::gnu();
276276
test.gcc()
277-
.target(&target)
278-
.host(&target)
277+
.target(target)
278+
.host(target)
279279
.file("foo.c")
280280
.compile("foo");
281281

@@ -511,7 +511,9 @@ fn gnu_apple_darwin() {
511511
for (arch, version) in &[("x86_64", "10.7"), ("aarch64", "11.0")] {
512512
let target = format!("{}-apple-darwin", arch);
513513
let test = Test::gnu();
514-
test.gcc()
514+
test.shim("fake-gcc")
515+
.gcc()
516+
.compiler("fake-gcc")
515517
.target(&target)
516518
.host(&target)
517519
// Avoid test maintenance when minimum supported OSes change.
@@ -520,8 +522,7 @@ fn gnu_apple_darwin() {
520522
.compile("foo");
521523

522524
let cmd = test.cmd(0);
523-
test.cmd(0)
524-
.must_have(format!("-mmacosx-version-min={}", version));
525+
cmd.must_have(format!("-mmacosx-version-min={version}"));
525526
cmd.must_not_have("-isysroot");
526527
}
527528
}
@@ -553,7 +554,7 @@ fn macos_cpp_minimums() {
553554
let deployment_arg = exec
554555
.args
555556
.iter()
556-
.find_map(|arg| arg.strip_prefix("-mmacosx-version-min="))
557+
.find_map(|arg| arg.strip_prefix("--target=x86_64-apple-macosx"))
557558
.expect("no deployment target argument was set");
558559

559560
let mut deployment_parts = deployment_arg.split('.').map(|v| v.parse::<u32>().unwrap());
@@ -581,7 +582,7 @@ fn macos_cpp_minimums() {
581582
.compile("foo");
582583

583584
// No C++ leaves it untouched
584-
test.cmd(0).must_have("-mmacosx-version-min=10.7");
585+
test.cmd(0).must_have("--target=x86_64-apple-macosx10.7");
585586
}
586587

587588
#[cfg(target_os = "macos")]
@@ -596,7 +597,7 @@ fn clang_apple_tvos() {
596597
.file("foo.c")
597598
.compile("foo");
598599

599-
test.cmd(0).must_have("-mappletvos-version-min=9.0");
600+
test.cmd(0).must_have("--target=arm64-apple-tvos9.0");
600601
}
601602

602603
#[cfg(target_os = "macos")]
@@ -629,8 +630,8 @@ fn clang_apple_mac_catalyst() {
629630
"-iframework",
630631
&format!("{sdkroot}/System/iOSSupport/System/Library/Frameworks"),
631632
);
632-
execution.must_have(&format!("-L{sdkroot}/System/iOSSupport/usr/lib"));
633-
execution.must_have(&format!(
633+
execution.must_have(format!("-L{sdkroot}/System/iOSSupport/usr/lib"));
634+
execution.must_have(format!(
634635
"-F{sdkroot}/System/iOSSupport/System/Library/Frameworks"
635636
));
636637
}
@@ -648,7 +649,8 @@ fn clang_apple_tvsimulator() {
648649
.file("foo.c")
649650
.compile("foo");
650651

651-
test.cmd(0).must_have("-mappletvsimulator-version-min=9.0");
652+
test.cmd(0)
653+
.must_have("--target=x86_64-apple-tvos9.0-simulator");
652654
}
653655

654656
#[cfg(target_os = "macos")]

0 commit comments

Comments
 (0)