Skip to content

Commit a325fb8

Browse files
committed
Warn when running under Rosetta emulation
1 parent ab81ee3 commit a325fb8

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

src/cli/common.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ use crate::currentprocess::{
2020
terminalsource,
2121
varsource::VarSource,
2222
};
23+
use crate::dist::dist::{TargetTriple, ToolchainDesc};
24+
use crate::install::UpdateStatus;
2325
use crate::utils::notifications as util_notifications;
2426
use crate::utils::notify::NotificationLevel;
2527
use crate::utils::utils;
26-
use crate::{dist::dist::ToolchainDesc, install::UpdateStatus};
2728
use crate::{
2829
dist::notifications as dist_notifications, toolchain::distributable::DistributableToolchain,
2930
};
@@ -674,3 +675,14 @@ pub(crate) fn ignorable_error(error: &'static str, no_prompt: bool) -> Result<()
674675
Err(error)
675676
}
676677
}
678+
679+
/// Warns if rustup is running under emulation, such as macOS Rosetta
680+
pub(crate) fn warn_if_host_is_emulated() {
681+
if TargetTriple::is_host_emulated() {
682+
warn!(
683+
"Rustup is not running natively. It's running under emulation of {}.",
684+
TargetTriple::from_host_or_build()
685+
);
686+
warn!("For best compatibility and performance you should reinstall rustup for your native CPU.");
687+
}
688+
}

src/cli/rustup_mode.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,8 @@ fn maybe_upgrade_data(cfg: &Cfg, m: &ArgMatches) -> Result<bool> {
841841
}
842842

843843
fn default_(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
844+
common::warn_if_host_is_emulated();
845+
844846
if let Some(toolchain) = m.get_one::<MaybeResolvableToolchainName>("toolchain") {
845847
match toolchain.to_owned() {
846848
MaybeResolvableToolchainName::None => {
@@ -918,6 +920,7 @@ fn check_updates(cfg: &Cfg) -> Result<utils::ExitCode> {
918920
}
919921

920922
fn update(cfg: &mut Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
923+
common::warn_if_host_is_emulated();
921924
let self_update_mode = cfg.get_self_update_mode()?;
922925
// Priority: no-self-update feature > self_update_mode > no-self-update args.
923926
// Update only if rustup does **not** have the no-self-update feature,
@@ -1051,6 +1054,8 @@ fn which(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
10511054

10521055
#[cfg_attr(feature = "otel", tracing::instrument(skip_all))]
10531056
fn show(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
1057+
common::warn_if_host_is_emulated();
1058+
10541059
let verbose = m.get_flag("verbose");
10551060

10561061
// Print host triple

src/cli/self_update.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ fn do_pre_install_sanity_checks(no_prompt: bool) -> Result<()> {
589589
}
590590

591591
fn do_pre_install_options_sanity_checks(opts: &InstallOpts<'_>) -> Result<()> {
592+
common::warn_if_host_is_emulated();
593+
592594
// Verify that the installation options are vaguely sane
593595
(|| {
594596
let host_triple = opts
@@ -1058,6 +1060,8 @@ pub(crate) fn uninstall(no_prompt: bool) -> Result<utils::ExitCode> {
10581060
/// rustup-init is stored in `CARGO_HOME`/bin, and then deleted next
10591061
/// time rustup runs.
10601062
pub(crate) fn update(cfg: &Cfg) -> Result<utils::ExitCode> {
1063+
common::warn_if_host_is_emulated();
1064+
10611065
use common::SelfUpdatePermission::*;
10621066
let update_permitted = if NEVER_SELF_UPDATE {
10631067
HardFail

src/dist/dist.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,28 @@ impl TargetTriple {
232232
}
233233
}
234234

235+
#[cfg(not(target_os = "macos"))]
236+
pub(crate) fn is_host_emulated() -> bool {
237+
false
238+
}
239+
240+
/// Detects Rosetta emulation on macOS
241+
#[cfg(target_os = "macos")]
242+
pub(crate) fn is_host_emulated() -> bool {
243+
unsafe {
244+
let mut ret: libc::c_int = 0;
245+
let mut size = std::mem::size_of::<libc::c_int>() as libc::size_t;
246+
let err = libc::sysctlbyname(
247+
b"sysctl.proc_translated\0".as_ptr().cast(),
248+
(&mut ret) as *mut _ as *mut libc::c_void,
249+
&mut size,
250+
std::ptr::null_mut(),
251+
0,
252+
);
253+
err == 0 && ret != 0
254+
}
255+
}
256+
235257
pub(crate) fn from_host() -> Option<Self> {
236258
#[cfg(windows)]
237259
fn inner() -> Option<TargetTriple> {

0 commit comments

Comments
 (0)