Skip to content

Commit

Permalink
Add visionOS support (#1029)
Browse files Browse the repository at this point in the history
* Add visionOS support

* Fix visionOS deployment target name

* Do not emit -mxros-version-min=... as that is not yet supported

* Add simple test

* Only run test on newer Xcode versions
  • Loading branch information
madsmtm committed Apr 12, 2024
1 parent f313ff5 commit e80a19d
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 11 deletions.
76 changes: 65 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
};
Expand Down Expand Up @@ -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('-') {
Expand All @@ -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(_) => {}
};
Expand Down Expand Up @@ -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") {
Expand Down Expand Up @@ -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.
_ => {}
}

Expand Down Expand Up @@ -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()),
}
}

Expand Down Expand Up @@ -3792,6 +3843,7 @@ enum AppleOs {
Ios,
WatchOs,
TvOs,
VisionOS,
}

impl std::fmt::Debug for AppleOs {
Expand All @@ -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"),
}
}
}
Expand All @@ -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"),
Expand Down
26 changes: 26 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit e80a19d

Please sign in to comment.