2024-09-29 07:00:34 -05:00
|
|
|
//! Test codegen when setting SDK version on Apple platforms.
|
|
|
|
//!
|
|
|
|
//! This is important since its a compatibility hazard. The linker will
|
|
|
|
//! generate load commands differently based on what minimum OS it can assume.
|
|
|
|
//!
|
|
|
|
//! See https://github.com/rust-lang/rust/issues/129432.
|
|
|
|
|
|
|
|
//@ only-apple
|
|
|
|
|
|
|
|
use run_make_support::{apple_os, cmd, run_in_tmpdir, rustc, target};
|
|
|
|
|
|
|
|
/// Run vtool to check the `sdk` field in LC_BUILD_VERSION.
|
|
|
|
///
|
|
|
|
/// On lower deployment targets, LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS and similar
|
|
|
|
/// are used instead of LC_BUILD_VERSION, but both name the relevant variable `sdk`.
|
|
|
|
#[track_caller]
|
|
|
|
fn has_sdk_version(file: &str, version: &str) {
|
|
|
|
cmd("vtool")
|
|
|
|
.arg("-show-build")
|
|
|
|
.arg(file)
|
|
|
|
.run()
|
|
|
|
.assert_stdout_contains(format!("sdk {version}"));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
// Fetch rustc's inferred deployment target.
|
|
|
|
let current_deployment_target =
|
|
|
|
rustc().target(target()).print("deployment-target").run().stdout_utf8();
|
|
|
|
let current_deployment_target =
|
|
|
|
current_deployment_target.strip_prefix("deployment_target=").unwrap().trim();
|
|
|
|
|
|
|
|
// Fetch current SDK version via. xcrun.
|
|
|
|
//
|
|
|
|
// Assumes a standard Xcode distribution, where e.g. the macOS SDK's Mac Catalyst
|
|
|
|
// and the iPhone Simulator version is the same as for the iPhone SDK.
|
|
|
|
let sdk_name = match apple_os() {
|
|
|
|
"macos" => "macosx",
|
|
|
|
"ios" => "iphoneos",
|
|
|
|
"watchos" => "watchos",
|
|
|
|
"tvos" => "appletvos",
|
|
|
|
"visionos" => "xros",
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
|
|
|
let current_sdk_version =
|
|
|
|
cmd("xcrun").arg("--show-sdk-version").arg("--sdk").arg(sdk_name).run().stdout_utf8();
|
|
|
|
let current_sdk_version = current_sdk_version.trim();
|
|
|
|
|
|
|
|
// Check the SDK version in the object file produced by the codegen backend.
|
|
|
|
rustc().target(target()).crate_type("lib").emit("obj").input("foo.rs").output("foo.o").run();
|
|
|
|
// Set to 0, which means not set or "n/a".
|
|
|
|
has_sdk_version("foo.o", "n/a");
|
|
|
|
|
2024-09-29 06:58:49 -05:00
|
|
|
// Check the SDK version in the .rmeta file, as set in `create_object_file`.
|
|
|
|
//
|
|
|
|
// This is just to ensure that we don't set some odd version in `create_object_file`,
|
|
|
|
// if the rmeta file is packed in a different way in the future, this can safely be removed.
|
|
|
|
rustc().target(target()).crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
|
|
|
|
// Extra .rmeta file (which is encoded as an object file).
|
|
|
|
cmd("ar").arg("-x").arg("libfoo.rlib").arg("lib.rmeta").run();
|
|
|
|
has_sdk_version("lib.rmeta", "n/a");
|
|
|
|
|
2024-09-29 07:00:34 -05:00
|
|
|
// Test that version makes it to the linker.
|
|
|
|
for (crate_type, file_ext) in [("bin", ""), ("dylib", ".dylib")] {
|
|
|
|
// Non-simulator watchOS targets don't support dynamic linking,
|
|
|
|
// for simplicity we disable the test on all watchOS targets.
|
|
|
|
if crate_type == "dylib" && apple_os() == "watchos" {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test with clang
|
|
|
|
let file_name = format!("foo_cc{file_ext}");
|
|
|
|
rustc()
|
|
|
|
.target(target())
|
|
|
|
.crate_type("bin")
|
|
|
|
.arg("-Clinker-flavor=gcc")
|
|
|
|
.input("foo.rs")
|
|
|
|
.output(&file_name)
|
|
|
|
.run();
|
|
|
|
has_sdk_version(&file_name, current_sdk_version);
|
|
|
|
|
|
|
|
// Test with ld64
|
|
|
|
let file_name = format!("foo_ld{file_ext}");
|
|
|
|
rustc()
|
|
|
|
.target(target())
|
|
|
|
.crate_type("bin")
|
|
|
|
.arg("-Clinker-flavor=ld")
|
|
|
|
.input("foo.rs")
|
|
|
|
.output(&file_name)
|
|
|
|
.run();
|
|
|
|
// FIXME(madsmtm): This uses the current deployment target
|
|
|
|
// instead of the current SDK version like Clang does.
|
|
|
|
// https://github.com/rust-lang/rust/issues/129432
|
|
|
|
has_sdk_version(&file_name, current_deployment_target);
|
|
|
|
}
|
|
|
|
}
|