From a427d418fd0004f12a7d59899e6994238daed9aa Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Mon, 5 Dec 2022 23:15:16 -0600 Subject: [PATCH] Add deployment-target --print flag for Apple targets --- compiler/rustc_driver_impl/src/lib.rs | 16 +++++++ compiler/rustc_session/src/config.rs | 4 +- compiler/rustc_target/src/spec/apple_base.rs | 42 ++++++++++++++----- compiler/rustc_target/src/spec/mod.rs | 1 + src/doc/rustc/src/command-line-arguments.md | 6 +++ src/tools/tidy/src/ui_tests.rs | 2 +- .../valid-print-requests.stderr | 2 +- tests/ui/deployment-target/invalid-target.rs | 4 ++ .../deployment-target/invalid-target.stderr | 2 + tests/ui/deployment-target/macos-target.rs | 7 ++++ .../ui/deployment-target/macos-target.stdout | 1 + 11 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 tests/ui/deployment-target/invalid-target.rs create mode 100644 tests/ui/deployment-target/invalid-target.stderr create mode 100644 tests/ui/deployment-target/macos-target.rs create mode 100644 tests/ui/deployment-target/macos-target.stdout diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 5fac485de64..b9fb944b0c6 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -745,6 +745,22 @@ fn print_crate_info( } } } + DeploymentTarget => { + use rustc_target::spec::current_apple_deployment_target; + + if sess.target.is_like_osx { + safe_println!( + "deployment_target={}", + current_apple_deployment_target(&sess.target) + .expect("unknown Apple target OS") + ) + } else { + early_error( + ErrorOutputType::default(), + "only Apple targets currently support deployment version info", + ) + } + } } } Compilation::Stop diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index cfdba1120ec..a398c70c9a0 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -587,6 +587,7 @@ pub enum PrintRequest { StackProtectorStrategies, LinkArgs, SplitDebuginfo, + DeploymentTarget, } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -1452,7 +1453,7 @@ pub fn rustc_short_optgroups() -> Vec { "[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\ target-list|target-cpus|target-features|relocation-models|code-models|\ tls-models|target-spec-json|all-target-specs-json|native-static-libs|\ - stack-protector-strategies|link-args]", + stack-protector-strategies|link-args|deployment-target]", ), opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"), opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"), @@ -1902,6 +1903,7 @@ fn collect_print_requests( ("all-target-specs-json", PrintRequest::AllTargetSpecs), ("link-args", PrintRequest::LinkArgs), ("split-debuginfo", PrintRequest::SplitDebuginfo), + ("deployment-target", PrintRequest::DeploymentTarget), ]; prints.extend(matches.opt_strs("print").into_iter().map(|req| { diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 4c7f64b2078..ff224631828 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, env}; use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs}; -use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, TargetOptions}; +use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, Target, TargetOptions}; #[cfg(test)] #[path = "apple/tests.rs"] @@ -179,12 +179,28 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { } } -fn deployment_target(var_name: &str) -> Option<(u32, u32)> { - let deployment_target = env::var(var_name).ok(); - deployment_target - .as_ref() - .and_then(|s| s.split_once('.')) - .and_then(|(a, b)| a.parse::().and_then(|a| b.parse::().map(|b| (a, b))).ok()) +pub fn deployment_target(target: &Target) -> Option { + let (major, minor) = match &*target.os { + "macos" => { + // This does not need to be specific. It just needs to handle x86 vs M1. + let arch = if target.arch == "x86" || target.arch == "x86_64" { X86_64 } else { Arm64 }; + macos_deployment_target(arch) + } + "ios" => ios_deployment_target(), + "watchos" => watchos_deployment_target(), + "tvos" => tvos_deployment_target(), + _ => return None, + }; + + Some(format!("{major}.{minor}")) +} + +fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> { + let deployment_target = env::var(var_name).ok()?; + let (unparsed_major, unparsed_minor) = deployment_target.split_once('.')?; + let (major, minor) = (unparsed_major.parse().ok()?, unparsed_minor.parse().ok()?); + + Some((major, minor)) } fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { @@ -198,7 +214,8 @@ fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { } fn macos_deployment_target(arch: Arch) -> (u32, u32) { - deployment_target("MACOSX_DEPLOYMENT_TARGET") + // If you are looking for the default deployment target, prefer `rustc --print deployment-target`. + from_set_deployment_target("MACOSX_DEPLOYMENT_TARGET") .unwrap_or_else(|| macos_default_deployment_target(arch)) } @@ -247,7 +264,8 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> } fn ios_deployment_target() -> (u32, u32) { - deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0)) + // If you are looking for the default deployment target, prefer `rustc --print deployment-target`. + from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0)) } pub fn ios_llvm_target(arch: Arch) -> String { @@ -272,7 +290,8 @@ pub fn ios_sim_llvm_target(arch: Arch) -> String { } fn tvos_deployment_target() -> (u32, u32) { - deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0)) + // If you are looking for the default deployment target, prefer `rustc --print deployment-target`. + from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0)) } fn tvos_lld_platform_version() -> String { @@ -281,7 +300,8 @@ fn tvos_lld_platform_version() -> String { } fn watchos_deployment_target() -> (u32, u32) { - deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0)) + // If you are looking for the default deployment target, prefer `rustc --print deployment-target`. + from_set_deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0)) } fn watchos_lld_platform_version() -> String { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 10d38c34919..ba4b89c9ea1 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -60,6 +60,7 @@ pub mod crt_objects; mod aix_base; mod android_base; mod apple_base; +pub use apple_base::deployment_target as current_apple_deployment_target; mod avr_gnu_base; mod bpf_base; mod dragonfly_base; diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index d4d26654ed1..3be4382b0a3 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -248,8 +248,14 @@ The valid types of print values are: exact format of this debugging output is not a stable guarantee, other than that it will include the linker executable and the text of each command-line argument passed to the linker. +- `deployment-target` - The currently selected [deployment target] (or minimum OS version) + for the selected Apple platform target. This value can be used or passed along to other + components alongside a Rust build that need this information, such as C compilers. + This returns rustc's minimum supported deployment target if no `*_DEPLOYMENT_TARGET` variable + is present in the environment, or otherwise returns the variable's parsed value. [conditional compilation]: ../reference/conditional-compilation.html +[deployment target]: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html ## `-g`: include debug information diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index a2f7b8ba7be..e4f328ec0dd 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1953; -const ROOT_ENTRY_LIMIT: usize = 894; +const ROOT_ENTRY_LIMIT: usize = 895; fn check_entries(tests_path: &Path, bad: &mut bool) { let mut directories: HashMap = HashMap::new(); diff --git a/tests/run-make/valid-print-requests/valid-print-requests.stderr b/tests/run-make/valid-print-requests/valid-print-requests.stderr index bea6ce067f6..4f57550c29a 100644 --- a/tests/run-make/valid-print-requests/valid-print-requests.stderr +++ b/tests/run-make/valid-print-requests/valid-print-requests.stderr @@ -1,2 +1,2 @@ -error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `all-target-specs-json`, `link-args`, `split-debuginfo` +error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `all-target-specs-json`, `link-args`, `split-debuginfo`, `deployment-target` diff --git a/tests/ui/deployment-target/invalid-target.rs b/tests/ui/deployment-target/invalid-target.rs new file mode 100644 index 00000000000..336624320a3 --- /dev/null +++ b/tests/ui/deployment-target/invalid-target.rs @@ -0,0 +1,4 @@ +// compile-flags: --target x86_64-unknown-linux-gnu --print deployment-target +// needs-llvm-components: x86 + +fn main() {} diff --git a/tests/ui/deployment-target/invalid-target.stderr b/tests/ui/deployment-target/invalid-target.stderr new file mode 100644 index 00000000000..eb4ac131c40 --- /dev/null +++ b/tests/ui/deployment-target/invalid-target.stderr @@ -0,0 +1,2 @@ +error: only Apple targets currently support deployment version info + diff --git a/tests/ui/deployment-target/macos-target.rs b/tests/ui/deployment-target/macos-target.rs new file mode 100644 index 00000000000..701ccf4799a --- /dev/null +++ b/tests/ui/deployment-target/macos-target.rs @@ -0,0 +1,7 @@ +// only-macos +// compile-flags: --print deployment-target +// normalize-stdout-test: "\d+\." -> "$$CURRENT_MAJOR_VERSION." +// normalize-stdout-test: "\d+" -> "$$CURRENT_MINOR_VERSION" +// check-pass + +fn main() {} diff --git a/tests/ui/deployment-target/macos-target.stdout b/tests/ui/deployment-target/macos-target.stdout new file mode 100644 index 00000000000..f55ef568ed6 --- /dev/null +++ b/tests/ui/deployment-target/macos-target.stdout @@ -0,0 +1 @@ +deployment_target=$CURRENT_MAJOR_VERSION.$CURRENT_MINOR_VERSION