refactor: Move env parsing of deployment target to rustc_session
This commit is contained in:
parent
d74ce25b65
commit
7e4379c4eb
11 changed files with 74 additions and 75 deletions
|
@ -4,12 +4,6 @@ codegen_ssa_add_native_library = failed to add native library {$library_path}: {
|
||||||
|
|
||||||
codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work
|
codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work
|
||||||
|
|
||||||
codegen_ssa_apple_deployment_target_invalid =
|
|
||||||
failed to parse deployment target specified in {$env_var}: {$error}
|
|
||||||
|
|
||||||
codegen_ssa_apple_deployment_target_too_low =
|
|
||||||
deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
|
|
||||||
|
|
||||||
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
|
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
|
||||||
|
|
||||||
codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
|
codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use std::env;
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::str::FromStr;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
@ -11,7 +9,7 @@ use rustc_target::spec::Target;
|
||||||
pub(super) use rustc_target::spec::apple::OSVersion;
|
pub(super) use rustc_target::spec::apple::OSVersion;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::errors::{AppleDeploymentTarget, XcrunError, XcrunSdkPathWarning};
|
use crate::errors::{XcrunError, XcrunSdkPathWarning};
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -134,54 +132,6 @@ pub(super) fn add_data_and_relocation(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Name of the environment variable used to fetch the deployment target on the given OS.
|
|
||||||
pub fn deployment_target_env_var(os: &str) -> &'static str {
|
|
||||||
match os {
|
|
||||||
"macos" => "MACOSX_DEPLOYMENT_TARGET",
|
|
||||||
"ios" => "IPHONEOS_DEPLOYMENT_TARGET",
|
|
||||||
"watchos" => "WATCHOS_DEPLOYMENT_TARGET",
|
|
||||||
"tvos" => "TVOS_DEPLOYMENT_TARGET",
|
|
||||||
"visionos" => "XROS_DEPLOYMENT_TARGET",
|
|
||||||
_ => unreachable!("tried to get deployment target env var for non-Apple platform"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the deployment target based on the standard environment variables, or fall back to the
|
|
||||||
/// minimum version supported by `rustc`.
|
|
||||||
pub fn deployment_target(sess: &Session) -> OSVersion {
|
|
||||||
let min = OSVersion::minimum_deployment_target(&sess.target);
|
|
||||||
let env_var = deployment_target_env_var(&sess.target.os);
|
|
||||||
|
|
||||||
if let Ok(deployment_target) = env::var(env_var) {
|
|
||||||
match OSVersion::from_str(&deployment_target) {
|
|
||||||
Ok(version) => {
|
|
||||||
let os_min = OSVersion::os_minimum_deployment_target(&sess.target.os);
|
|
||||||
// It is common that the deployment target is set a bit too low, for example on
|
|
||||||
// macOS Aarch64 to also target older x86_64. So we only want to warn when variable
|
|
||||||
// is lower than the minimum OS supported by rustc, not when the variable is lower
|
|
||||||
// than the minimum for a specific target.
|
|
||||||
if version < os_min {
|
|
||||||
sess.dcx().emit_warn(AppleDeploymentTarget::TooLow {
|
|
||||||
env_var,
|
|
||||||
version: version.fmt_pretty().to_string(),
|
|
||||||
os_min: os_min.fmt_pretty().to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raise the deployment target to the minimum supported.
|
|
||||||
version.max(min)
|
|
||||||
}
|
|
||||||
Err(error) => {
|
|
||||||
sess.dcx().emit_err(AppleDeploymentTarget::Invalid { env_var, error });
|
|
||||||
min
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If no deployment target variable is set, default to the minimum found above.
|
|
||||||
min
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn add_version_to_llvm_target(
|
pub(super) fn add_version_to_llvm_target(
|
||||||
llvm_target: &str,
|
llvm_target: &str,
|
||||||
deployment_target: OSVersion,
|
deployment_target: OSVersion,
|
||||||
|
|
|
@ -3115,7 +3115,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
||||||
_ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"),
|
_ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let min_version = apple::deployment_target(sess).fmt_full().to_string();
|
let min_version = sess.apple_deployment_target().fmt_full().to_string();
|
||||||
|
|
||||||
// The SDK version is used at runtime when compiling with a newer SDK / version of Xcode:
|
// The SDK version is used at runtime when compiling with a newer SDK / version of Xcode:
|
||||||
// - By dyld to give extra warnings and errors, see e.g.:
|
// - By dyld to give extra warnings and errors, see e.g.:
|
||||||
|
@ -3184,7 +3184,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
||||||
|
|
||||||
// The presence of `-mmacosx-version-min` makes CC default to
|
// The presence of `-mmacosx-version-min` makes CC default to
|
||||||
// macOS, and it sets the deployment target.
|
// macOS, and it sets the deployment target.
|
||||||
let version = apple::deployment_target(sess).fmt_full();
|
let version = sess.apple_deployment_target().fmt_full();
|
||||||
// Intentionally pass this as a single argument, Clang doesn't
|
// Intentionally pass this as a single argument, Clang doesn't
|
||||||
// seem to like it otherwise.
|
// seem to like it otherwise.
|
||||||
cmd.cc_arg(&format!("-mmacosx-version-min={version}"));
|
cmd.cc_arg(&format!("-mmacosx-version-min={version}"));
|
||||||
|
|
|
@ -394,7 +394,7 @@ fn macho_object_build_version_for_target(sess: &Session) -> object::write::MachO
|
||||||
}
|
}
|
||||||
|
|
||||||
let platform = apple::macho_platform(&sess.target);
|
let platform = apple::macho_platform(&sess.target);
|
||||||
let min_os = apple::deployment_target(sess);
|
let min_os = sess.apple_deployment_target();
|
||||||
|
|
||||||
let mut build_version = object::write::MachOBuildVersion::default();
|
let mut build_version = object::write::MachOBuildVersion::default();
|
||||||
build_version.platform = platform;
|
build_version.platform = platform;
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub mod write;
|
||||||
/// Certain optimizations also depend on the deployment target.
|
/// Certain optimizations also depend on the deployment target.
|
||||||
pub fn versioned_llvm_target(sess: &Session) -> Cow<'_, str> {
|
pub fn versioned_llvm_target(sess: &Session) -> Cow<'_, str> {
|
||||||
if sess.target.is_like_darwin {
|
if sess.target.is_like_darwin {
|
||||||
apple::add_version_to_llvm_target(&sess.target.llvm_target, apple::deployment_target(sess))
|
apple::add_version_to_llvm_target(&sess.target.llvm_target, sess.apple_deployment_target())
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
// FIXME(madsmtm): Certain other targets also include a version,
|
// FIXME(madsmtm): Certain other targets also include a version,
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
use std::num::ParseIntError;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::ExitStatus;
|
use std::process::ExitStatus;
|
||||||
|
|
||||||
|
@ -738,14 +737,6 @@ pub enum ExtractBundledLibsError<'a> {
|
||||||
ExtractSection { rlib: &'a Path, error: Box<dyn std::error::Error> },
|
ExtractSection { rlib: &'a Path, error: Box<dyn std::error::Error> },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
pub(crate) enum AppleDeploymentTarget {
|
|
||||||
#[diag(codegen_ssa_apple_deployment_target_invalid)]
|
|
||||||
Invalid { env_var: &'static str, error: ParseIntError },
|
|
||||||
#[diag(codegen_ssa_apple_deployment_target_too_low)]
|
|
||||||
TooLow { env_var: &'static str, version: String, os_min: String },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(codegen_ssa_read_file)]
|
#[diag(codegen_ssa_read_file)]
|
||||||
pub(crate) struct ReadFileError {
|
pub(crate) struct ReadFileError {
|
||||||
|
|
|
@ -34,7 +34,6 @@ use std::time::{Instant, SystemTime};
|
||||||
use std::{env, str};
|
use std::{env, str};
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_codegen_ssa::back::apple;
|
|
||||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||||
use rustc_codegen_ssa::{CodegenErrors, CodegenResults};
|
use rustc_codegen_ssa::{CodegenErrors, CodegenResults};
|
||||||
use rustc_data_structures::profiling::{
|
use rustc_data_structures::profiling::{
|
||||||
|
@ -810,8 +809,8 @@ fn print_crate_info(
|
||||||
if sess.target.is_like_darwin {
|
if sess.target.is_like_darwin {
|
||||||
println_info!(
|
println_info!(
|
||||||
"{}={}",
|
"{}={}",
|
||||||
apple::deployment_target_env_var(&sess.target.os),
|
rustc_target::spec::apple::deployment_target_env_var(&sess.target.os),
|
||||||
apple::deployment_target(sess).fmt_pretty(),
|
sess.apple_deployment_target().fmt_pretty(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
session_apple_deployment_target_invalid =
|
||||||
|
failed to parse deployment target specified in {$env_var}: {$error}
|
||||||
|
|
||||||
|
session_apple_deployment_target_too_low =
|
||||||
|
deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
|
||||||
|
|
||||||
session_binary_float_literal_not_supported = binary float literal is not supported
|
session_binary_float_literal_not_supported = binary float literal is not supported
|
||||||
session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64
|
session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::num::NonZero;
|
use std::num::{NonZero, ParseIntError};
|
||||||
|
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::util::literal::LitError;
|
use rustc_ast::util::literal::LitError;
|
||||||
|
@ -14,6 +14,14 @@ use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTuple};
|
||||||
use crate::config::CrateType;
|
use crate::config::CrateType;
|
||||||
use crate::parse::ParseSess;
|
use crate::parse::ParseSess;
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
pub(crate) enum AppleDeploymentTarget {
|
||||||
|
#[diag(session_apple_deployment_target_invalid)]
|
||||||
|
Invalid { env_var: &'static str, error: ParseIntError },
|
||||||
|
#[diag(session_apple_deployment_target_too_low)]
|
||||||
|
TooLow { env_var: &'static str, version: String, os_min: String },
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct FeatureGateError {
|
pub(crate) struct FeatureGateError {
|
||||||
pub(crate) span: MultiSpan,
|
pub(crate) span: MultiSpan,
|
||||||
pub(crate) explain: DiagMessage,
|
pub(crate) explain: DiagMessage,
|
||||||
|
|
|
@ -29,7 +29,7 @@ use rustc_target::asm::InlineAsmArch;
|
||||||
use rustc_target::spec::{
|
use rustc_target::spec::{
|
||||||
CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
|
CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
|
||||||
SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target,
|
SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target,
|
||||||
TargetTuple, TlsModel,
|
TargetTuple, TlsModel, apple,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::code_stats::CodeStats;
|
use crate::code_stats::CodeStats;
|
||||||
|
@ -891,6 +891,45 @@ impl Session {
|
||||||
FileNameDisplayPreference::Local
|
FileNameDisplayPreference::Local
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the deployment target on Apple platforms based on the standard environment variables,
|
||||||
|
/// or fall back to the minimum version supported by `rustc`.
|
||||||
|
///
|
||||||
|
/// This should be guarded behind `if sess.target.is_like_darwin`.
|
||||||
|
pub fn apple_deployment_target(&self) -> apple::OSVersion {
|
||||||
|
let min = apple::OSVersion::minimum_deployment_target(&self.target);
|
||||||
|
let env_var = apple::deployment_target_env_var(&self.target.os);
|
||||||
|
|
||||||
|
// FIXME(madsmtm): Track changes to this.
|
||||||
|
if let Ok(deployment_target) = env::var(env_var) {
|
||||||
|
match apple::OSVersion::from_str(&deployment_target) {
|
||||||
|
Ok(version) => {
|
||||||
|
let os_min = apple::OSVersion::os_minimum_deployment_target(&self.target.os);
|
||||||
|
// It is common that the deployment target is set a bit too low, for example on
|
||||||
|
// macOS Aarch64 to also target older x86_64. So we only want to warn when variable
|
||||||
|
// is lower than the minimum OS supported by rustc, not when the variable is lower
|
||||||
|
// than the minimum for a specific target.
|
||||||
|
if version < os_min {
|
||||||
|
self.dcx().emit_warn(errors::AppleDeploymentTarget::TooLow {
|
||||||
|
env_var,
|
||||||
|
version: version.fmt_pretty().to_string(),
|
||||||
|
os_min: os_min.fmt_pretty().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raise the deployment target to the minimum supported.
|
||||||
|
version.max(min)
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
self.dcx().emit_err(errors::AppleDeploymentTarget::Invalid { env_var, error });
|
||||||
|
min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no deployment target variable is set, default to the minimum found above.
|
||||||
|
min
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JUSTIFICATION: part of session construction
|
// JUSTIFICATION: part of session construction
|
||||||
|
|
|
@ -317,3 +317,15 @@ impl OSVersion {
|
||||||
Self { major, minor, patch }
|
Self { major, minor, patch }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Name of the environment variable used to fetch the deployment target on the given OS.
|
||||||
|
pub fn deployment_target_env_var(os: &str) -> &'static str {
|
||||||
|
match os {
|
||||||
|
"macos" => "MACOSX_DEPLOYMENT_TARGET",
|
||||||
|
"ios" => "IPHONEOS_DEPLOYMENT_TARGET",
|
||||||
|
"watchos" => "WATCHOS_DEPLOYMENT_TARGET",
|
||||||
|
"tvos" => "TVOS_DEPLOYMENT_TARGET",
|
||||||
|
"visionos" => "XROS_DEPLOYMENT_TARGET",
|
||||||
|
_ => unreachable!("tried to get deployment target env var for non-Apple platform"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue