From a325fb81138b6dec521ff47f614fc1d6915d90a2 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 36b3d7eeba..453d0cbc07 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 8dd6577750..fef44cfbf7 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -841,6 +841,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 => { @@ -918,6 +920,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, @@ -1051,6 +1054,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 3399943f0c..3c27291574 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -589,6 +589,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 @@ -1058,6 +1060,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 cfbdc68fec..959bef3371 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -232,6 +232,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 {