From 0907089ccdc3b2848200a3c4350d5789e3bbe6b5 Mon Sep 17 00:00:00 2001 From: Kornel Date: Thu, 8 Sep 2022 12:34:29 +0100 Subject: [PATCH] Warn when running under Rosetta emulation --- src/cli/common.rs | 14 +++++++++++++- src/cli/rustup_mode.rs | 5 +++++ src/cli/self_update.rs | 4 ++++ src/dist/dist.rs | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index e9f3d700dd..a0c9ca7b2d 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -20,10 +20,11 @@ use crate::currentprocess::{ terminalsource, varsource::VarSource, }; +use crate::dist::dist::{TargetTriple, ToolchainDesc}; +use crate::install::UpdateStatus; use crate::utils::notifications as util_notifications; use crate::utils::notify::NotificationLevel; use crate::utils::utils; -use crate::{dist::dist::ToolchainDesc, install::UpdateStatus}; use crate::{ dist::notifications as dist_notifications, toolchain::distributable::DistributableToolchain, }; @@ -674,3 +675,14 @@ pub(crate) fn ignorable_error(error: &'static str, no_prompt: bool) -> Result<() Err(error) } } + +/// Warns if rustup is running under emulation, such as macOS Rosetta +pub(crate) fn warn_if_host_is_emulated() { + if TargetTriple::is_host_emulated() { + warn!( + "Rustup is not running natively. It's running under emulation of {}.", + TargetTriple::from_host_or_build() + ); + warn!("For best compatibility and performance you should reinstall rustup for your native CPU."); + } +} diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index e29c189754..0be87295cb 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -840,6 +840,8 @@ fn maybe_upgrade_data(cfg: &Cfg, m: &ArgMatches) -> Result { } fn default_(cfg: &Cfg, m: &ArgMatches) -> Result { + common::warn_if_host_is_emulated(); + if let Some(toolchain) = m.get_one::("toolchain") { match toolchain.to_owned() { MaybeResolvableToolchainName::None => { @@ -917,6 +919,7 @@ fn check_updates(cfg: &Cfg) -> Result { } fn update(cfg: &mut Cfg, m: &ArgMatches) -> Result { + common::warn_if_host_is_emulated(); let self_update_mode = cfg.get_self_update_mode()?; // Priority: no-self-update feature > self_update_mode > no-self-update args. // Update only if rustup does **not** have the no-self-update feature, @@ -1050,6 +1053,8 @@ fn which(cfg: &Cfg, m: &ArgMatches) -> Result { #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn show(cfg: &Cfg, m: &ArgMatches) -> Result { + common::warn_if_host_is_emulated(); + let verbose = m.get_flag("verbose"); // Print host triple diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index 4ccf7b3653..8c21038a4c 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -604,6 +604,8 @@ fn do_pre_install_sanity_checks(no_prompt: bool) -> Result<()> { } fn do_pre_install_options_sanity_checks(opts: &InstallOpts<'_>) -> Result<()> { + common::warn_if_host_is_emulated(); + // Verify that the installation options are vaguely sane (|| { let host_triple = opts @@ -1073,6 +1075,8 @@ pub(crate) fn uninstall(no_prompt: bool) -> Result { /// rustup-init is stored in `CARGO_HOME`/bin, and then deleted next /// time rustup runs. pub(crate) fn update(cfg: &Cfg) -> Result { + common::warn_if_host_is_emulated(); + use common::SelfUpdatePermission::*; let update_permitted = if NEVER_SELF_UPDATE { HardFail diff --git a/src/dist/dist.rs b/src/dist/dist.rs index ceceae331e..78932111ac 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -253,6 +253,28 @@ impl TargetTriple { } } + #[cfg(not(target_os = "macos"))] + pub(crate) fn is_host_emulated() -> bool { + false + } + + /// Detects Rosetta emulation on macOS + #[cfg(target_os = "macos")] + pub(crate) fn is_host_emulated() -> bool { + unsafe { + let mut ret: libc::c_int = 0; + let mut size = std::mem::size_of::() as libc::size_t; + let err = libc::sysctlbyname( + b"sysctl.proc_translated\0".as_ptr().cast(), + (&mut ret) as *mut _ as *mut libc::c_void, + &mut size, + std::ptr::null_mut(), + 0, + ); + err == 0 && ret != 0 + } + } + pub(crate) fn from_host() -> Option { #[cfg(windows)] fn inner() -> Option {