Skip to content

Commit

Permalink
Emit diagnostics for incorrect deployment targets
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Oct 2, 2024
1 parent 028893d commit 3bba2a8
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 11 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not imp
codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
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_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
Expand Down
42 changes: 34 additions & 8 deletions compiler/rustc_codegen_ssa/src/apple.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::borrow::Cow;
use std::env;
use std::fmt::{Display, from_fn};
use std::num::ParseIntError;

use rustc_middle::bug;
use rustc_session::Session;

use crate::errors::AppleDeploymentTarget;

#[cfg(test)]
mod tests;

Expand All @@ -13,6 +16,17 @@ mod tests;
/// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
pub type OsVersion = (u16, u8, u8);

pub fn pretty_version(version: OsVersion) -> impl Display {
let (major, minor, patch) = version;
from_fn(move |f| {
write!(f, "{major}.{minor}")?;
if patch != 0 {
write!(f, ".{patch}")?;
}
Ok(())
})
}

/// Parse an OS version triple (SDK version or deployment target).
fn parse_version(version: &str) -> Result<OsVersion, ParseIntError> {
if let Some((major, minor)) = version.split_once('.') {
Expand Down Expand Up @@ -74,14 +88,26 @@ pub fn deployment_target(sess: &Session) -> OsVersion {

if let Ok(deployment_target) = env::var(env_var) {
match parse_version(&deployment_target) {
// It is common that the deployment target is set too low, e.g. on macOS Aarch64 to also
// target older x86_64, the user may set a lower deployment target than supported.
//
// To avoid such issues, we silently raise the deployment target here.
// FIXME: We want to show a warning when `version < os_min`.
Ok(version) => version.max(min),
// FIXME: Report erroneous environment variable to user.
Err(_) => min,
Ok(version) => {
// 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: pretty_version(version).to_string(),
os_min: pretty_version(os_min).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.
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::borrow::Cow;
use std::io::Error;
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
use std::process::ExitStatus;

Expand Down Expand Up @@ -539,6 +540,14 @@ pub(crate) struct UnsupportedArch<'a> {
pub os: &'a str,
}

#[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)]
pub(crate) enum AppleSdkRootError<'a> {
#[diag(codegen_ssa_apple_sdk_error_sdk_path)]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(debug_closure_helpers)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
#![feature(let_chains)]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,10 +856,10 @@ fn print_crate_info(
}
}
DeploymentTarget => {
use rustc_codegen_ssa::apple::{deployment_target, pretty_version};

if sess.target.is_like_osx {
let (major, minor, patch) = rustc_codegen_ssa::apple::deployment_target(sess);
let patch = if patch != 0 { format!(".{patch}") } else { String::new() };
println_info!("deployment_target={major}.{minor}{patch}")
println_info!("deployment_target={}", pretty_version(deployment_target(sess)))
} else {
#[allow(rustc::diagnostic_outside_of_impl)]
sess.dcx().fatal("only Apple targets currently support deployment version info")
Expand Down

0 comments on commit 3bba2a8

Please sign in to comment.