diff --git a/src/lib.rs b/src/lib.rs index 17a9c057d..39cce8a23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1892,6 +1892,7 @@ impl Build { if !target.contains("apple-ios") && !target.contains("apple-watchos") && !target.contains("apple-tvos") + && !target.contains("apple-visionos") { cmd.push_cc_arg("-ffunction-sections".into()); cmd.push_cc_arg("-fdata-sections".into()); @@ -2033,6 +2034,42 @@ impl Build { format!("--target={}-apple-tvos{}", arch, deployment_target).into(), ); } + } else if target.contains("visionos-sim") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = apple_os_sdk_parts( + AppleOs::VisionOS, + &AppleArchSpec::Simulator(""), + ); + let deployment_target = self.apple_deployment_version( + AppleOs::VisionOS, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!( + "--target={}-apple-xros{}-simulator", + arch, deployment_target + ) + .into(), + ); + } + } else if target.contains("visionos") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = + apple_os_sdk_parts(AppleOs::VisionOS, &AppleArchSpec::Device("")); + let deployment_target = self.apple_deployment_version( + AppleOs::VisionOS, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!("--target={}-apple-xros{}", arch, deployment_target).into(), + ); + } } else if let Ok(index) = target_info::RISCV_ARCH_MAPPING .binary_search_by_key(&arch, |(arch, _)| &arch) { @@ -2536,6 +2573,8 @@ impl Build { AppleOs::WatchOs } else if target.contains("-tvos") { AppleOs::TvOs + } else if target.contains("-visionos") { + AppleOs::VisionOS } else { AppleOs::Ios }; @@ -2625,9 +2664,14 @@ impl Build { AppleArchSpec::Device(arch) => { cmd.args.push("-arch".into()); cmd.args.push(arch.into()); - cmd.args.push( - format!("-m{}os-version-min={}", sdk_details.sdk_prefix, min_version).into(), - ); + // `-mxros-version-min` does not exist + // https://github.com/llvm/llvm-project/issues/88271 + if os != AppleOs::VisionOS { + cmd.args.push( + format!("-m{}os-version-min={}", sdk_details.sdk_prefix, min_version) + .into(), + ); + } } AppleArchSpec::Simulator(arch) => { if arch.starts_with('-') { @@ -2637,13 +2681,15 @@ impl Build { cmd.args.push("-arch".into()); cmd.args.push(arch.into()); } - cmd.args.push( - format!( - "-m{}simulator-version-min={}", - sdk_details.sim_prefix, min_version - ) - .into(), - ); + if os != AppleOs::VisionOS { + cmd.args.push( + format!( + "-m{}simulator-version-min={}", + sdk_details.sim_prefix, min_version + ) + .into(), + ); + } } AppleArchSpec::Catalyst(_) => {} }; @@ -2805,6 +2851,7 @@ impl Build { } else if target.contains("apple-ios") | target.contains("apple-watchos") | target.contains("apple-tvos") + | target.contains("apple-visionos") { clang.to_string() } else if target.contains("android") { @@ -3720,7 +3767,7 @@ impl Build { return None; } } - // watchOS, tvOS, and others are all new enough that libc++ is their baseline. + // watchOS, tvOS, visionOS, and others are all new enough that libc++ is their baseline. _ => {} } @@ -3764,6 +3811,10 @@ impl Build { AppleOs::TvOs => deployment_from_env("TVOS_DEPLOYMENT_TARGET") .or_else(default_deployment_from_sdk) .unwrap_or_else(|| "9.0".into()), + + AppleOs::VisionOS => deployment_from_env("XROS_DEPLOYMENT_TARGET") + .or_else(default_deployment_from_sdk) + .unwrap_or_else(|| "1.0".into()), } } @@ -3792,6 +3843,7 @@ enum AppleOs { Ios, WatchOs, TvOs, + VisionOS, } impl std::fmt::Debug for AppleOs { @@ -3801,6 +3853,7 @@ impl std::fmt::Debug for AppleOs { AppleOs::Ios => f.write_str("iOS"), AppleOs::WatchOs => f.write_str("WatchOS"), AppleOs::TvOs => f.write_str("AppleTVOS"), + AppleOs::VisionOS => f.write_str("visionOS"), } } } @@ -3817,6 +3870,7 @@ fn apple_os_sdk_parts(os: AppleOs, arch: &AppleArchSpec) -> AppleSdkTargetParts AppleOs::Ios => ("iphone", "ios-"), AppleOs::WatchOs => ("watch", "watch"), AppleOs::TvOs => ("appletv", "appletv"), + AppleOs::VisionOS => ("xr", "xr"), }; let sdk = match arch { AppleArchSpec::Device(_) if os == AppleOs::MacOs => Cow::Borrowed("macosx"), diff --git a/tests/test.rs b/tests/test.rs index cd306896c..fac6a67b0 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -600,6 +600,32 @@ fn clang_apple_tvsimulator() { } } +#[cfg(target_os = "macos")] +#[test] +fn clang_apple_visionos() { + // Only run this test if visionOS is available on the host machine + let output = std::process::Command::new("xcrun") + .args(["--show-sdk-version", "--sdk", "xros"]) + .output() + .unwrap(); + if !output.status.success() { + return; + } + + let test = Test::clang(); + test.gcc() + .__set_env("XROS_DEPLOYMENT_TARGET", "1.0") + .target("aarch64-apple-visionos") + .file("foo.c") + .compile("foo"); + + dbg!(test.cmd(0).args); + + test.cmd(0).must_have("--target=arm64-apple-xros1.0"); + test.cmd(0).must_not_have("-mxros-version-min=1.0"); + test.cmd(0).must_not_have("-mxrsimulator-version-min=1.0"); +} + #[test] fn compile_intermediates() { let test = Test::gnu();