前幾天拿到了新的 M1 MacBook Air,想說來試試看一些平常使用的工具以及 iOS App,結果發現很多常用的 iOS App 都還沒有開放 macOS 下載使用…… 但很多常用的工具都已經有原生支援的版本了,在使用上也沒有什麼太多的問題,但有些小技巧想分享給大家,希望大家在這個轉換之路(?)上可以再更順暢一些~
Rosetta 2 相關
這裡會列出一些與 Intel 相容模式(Rosetta 2)有關的一些小技巧:
原生支援?
在活動監視器(Activity Monitor)可以看到一個叫做「建築」[1]的欄位,在這裡我們可以看到有分成 Apple 以及 Intel,分別對應到原生 Apple silicon 以及 Rosetta 2[2] 相容的 Intel 模式。
如果你發現正在執行的應用程式是 Intel 表示他正在 Rosetta 2 底下運作。
手動安裝 Rosetta 2
個人覺得這個技巧至關重要,因為我曾經在 11.0.1 升級到 11.1 之後,Rosetta 就消失了,導致我還在用 Intel 架構的輸入法(對!連輸入法都可以靠 Rosetta 相容)死亡,也不知道為什麼 macOS 沒有主動提醒我要再安裝一次 Rosetta,直到我要安裝別的 Intel 應用程式時才又提醒,當時我才恍然大悟,原來我的 Rosetta 在升級的時候消失了……
方法也很簡單,只要打開終端機然後用軟體升級的方式安裝就可以了:
$ /usr/sbin/softwareupdate --install-rosetta --agree-to-license
雖然加了 --agree-to-license
之後就不會提醒你再看一次 SLA,但第一次使用前還是看一下吧XD
強制使用 Rosetta 來執行 Universal 應用程式
蘋果在轉換到 Apple silicon 的時候提出了一個以前[3]也用過的解決方案,對於這樣的通用架構應用程式,我們可以透過「取得資訊」來將通用架構應用程式設定為使用 Rosetta 開啓。
透過 CLI 強制使用 Rosetta
前面講的是可以將 .app 應用程式以 Rosetta 方式開啓的技巧,但如果在 CLI 下的話該如何操作呢?
方法也很簡單,我們可以透過 arch
這個指令來幫我們跳入 x86_64
的世界:
$ which uname
/usr/bin/uname
$ file /usr/bin/uname
/usr/bin/uname: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/uname (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/uname (for architecture arm64e): Mach-O 64-bit executable arm64e
$ uname -u
arm64
$ arch -arch x86_64 uname -u
x86_64
$
同理,我們也可以靠 arch
指令來讓我們打開一個 x86_64 的 Shell,在裡面運作的程式就都會以 x86_64 優先了:
$ arch -arch x86_64 bash
[x86_64] $ uname -m
x86_64
$ arch -arch arm64e bash
[arm64e] $ uname -m
arm64
[arm64e] $
雖然這個範例中表示可以在 x86_64 模式下再跳回 arm64e 模式[4],但其實這件事情在 11.0.1 的時候還是不行的,會噴出不認識的 architecture 錯誤,但在 11.1 之後就可以了!
透過 sysctl 取得目前是不是在 Rosetta 中運作
這個也是一個實用的小技巧,我們可以透過 sysctl 瞭解目前的環境是不是在 Rosetta 中:
$ sysctl -n sysctl.proc_translated
0
$ arch -arch x86_64 sysctl -n sysctl.proc_translated
1
$
如果 sysctl.proc_translated
的值是 1
表示目前正在 Rosetta 中執行。
iOS App 相關
這裡會列出一些與 iOS App 相關的小技巧:
安裝 ipa 後無法執行
有時候會遇到安裝 .ipa 之後,macOS 卻阻止你執行的情況,這時候有可能是因為這個 App 被上了 com.apple.quarantine
這個屬性,我們只要用下面的方式就可以解開束縛:
$ sudo xattr -dr com.apple.quarantine <Installed.app>
通常這個屬性代表的是不安全的應用程式,例如從瀏覽器下載回來的應用程式就會自動打上這個屬性,只是不知道為何從 ipa 安裝的 App 並不會提醒你是否允許執行,而是直接拒絕你執行。
CLI 相關
這裡列出一些跟 CLI 有關的小技巧,如果是有關如何在 CLI 執行 Rosetta 的話可以往上面的節次看:
安裝 Homebrew
這好像不管是不是 M1 Mac 都會用到,但由於 Homebrew 散佈的執行檔都是單一架構的,所以這邊會另外展示如何安裝 Intel 架構的 Homebrew(以取得 Intel 架構的執行檔)。
Apple Silicon 版本的 Homebrew,按照原先的安裝方式就可以了:
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
再來是 Intel 架構的 Homebrew,雖然 Homebrew 是用 Ruby 撰寫而成,其實可以直接用前面提到的 arch
來切換至 Intel 架構執行,但我是建議把 Intel 架構用的 Homebrew 跟 Apple 架構用的 Homebrew 分開,避免 Homebrew 搞不清楚跨架構 library 之間的相依性。
所以我們需要用替代安裝[5]的方式把 Homebrew 安裝到指定的位置(這裡舉例是 /opt/homebrew.x86_64
):
$ mkdir -p /opt/homebrew.x86_64
$ curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C /opt/homebrew.x86_64
接下來我會在我的 Terminal 中設定兩個 Profile,一個是 Apple 架構的 Shell、另一個是 Intel 架構的(一樣用 arch
關進 Intel 模式)Shell,並且在 shellrc 中加入環境偵測來判斷使用哪個 Homebrew:
# ~/.zprofile
if [ "$(sysctl -n sysctl.proc_translated)" = "1" ]; then
eval $(/opt/homebrew.x86_64/bin/brew shellenv)
else
eval $(/opt/homebrew/bin/brew shellenv)
fi
# ~/.config/fish/config.fish
set is_rosetta (sysctl -n sysctl.proc_translated)
if [ $is_rosetta = '1' ]
set homebrew /opt/homebrew.x86_64/bin
else
set homebrew /opt/homebrew/bin
end
set default_path /usr/local/bin /usr/bin /usr/sbin /bin /sbin
set -gx PATH $homebrew $default_path
雜記
最後小小抱怨一下 macOS 11.0.1 根本就是還沒有完成的版本……
Bug 有夠多[6],而且還沒辦法做雙向轉換(人家 Windows <> WSL 就可以互相呼叫),好險 11.1 之後這些缺點都有補回來。
再用一陣子也許還會再增加一些技巧,不過基於我還在複習 macOS(畢竟有好多年沒用 Mac 了……),所以可能需要再一下下才會更新XD
個人猜測是 Architecture 的翻譯啦…… 近年來蘋果很多名詞都會刻意找一個中文翻譯…… 以前不會的啊 QQ ↩︎
Rosetta 2 可讓配備 Apple 晶片的 Mac 使用專為配備 Intel 處理器的 Mac 所開發的 App。 詳見 Apple 支援頁面 ↩︎
以前從 PowerPC 架構轉換至 Intel 架構時蘋果就有提出相同的解決方案,使得不同架構的應用程式可以同時存在於一個執行檔中。詳見維基百科的〈Universal Binary〉條目。 ↩︎
在
man arch
中有列出幾個可以使用的模式,包含:i386
,x86_64
,x86_64h
(Haswell),arm64
,arm64e
(Apple Silicon)。 ↩︎參考 Homebrew 安裝說明 ↩︎