Apple Silicon M1、M2 安裝舊版 Ruby 的方法

最近因為換了一台新 Macbook Air,我第一台使用蘋果晶片的 Mac, 在建置開發環境的過程為了一些老舊的專案,得安裝舊版 Ruby 2.3 , 使用 rvm install 2.3.1 踩了雷才知道要在新版 Mac(M1、M2 晶片) 安裝舊版本 Ruby 變成一件麻煩的事情, 所以把自己最終的解法記錄下來避免之後再次踩雷。

Ruby 2.4 以前的版本,對於 OpenSSL 依賴版本為 1.0, 而現在新環境內建的 OpenSSL 都已經為版本 3, 所以為了安裝舊版 Ruby 的條件就是要安裝 OpenSSL 1.0。

然而 Homebrew 已經沒有 1.0 的版本, 雖然 rbenv 有出一個 1.0 版的 OpenSSL,但是在編譯過程一樣會出錯:

Last 15 lines from /Users/yfxie/Library/Logs/Homebrew/[email protected]/03.make:
 ^
x86_64cpuid.s:273:10: error: unknown token in expression
 cmpq $0,%rax
         ^
x86_64cpuid.s:273:10: error: invalid operand
 cmpq $0,%rax
         ^
x86_64cpuid.s:274:9: error: unknown token in expression
 cmoveq %rcx,%rax
        ^
x86_64cpuid.s:274:9: error: invalid operand
 cmoveq %rcx,%rax
        ^
make[1]: *** [x86_64cpuid.o] Error 1
make: *** [build_crypto] Error 1

所以造成安裝舊版 Ruby 會變得麻煩成因大致為:

  1. 依賴 1.0 版的 OpenSSL。
  2. 使用 brew 無法直接找到版本符合的安裝源。
  3. 存在的版本又不適用於新的架構。
  4. 除了 OpenSSL 外還需要安裝 libffi 以解決 Ruby 在編譯時產生的另一個錯誤。

如果沒有安裝 libffi 以及設定環境變數,在安裝 Ruby 時可能會看到以下錯誤訊息 (實際上還是要看 make.log 內所印出的錯誤訊息為準):

ruby-2.3.1 - #compiling - please wait
Error running '__rvm_make -j8',
please read /Users/yfxie/.rvm/log/1668350787_ruby-2.3.1/make.log

There has been an error while running make. Halting the installation.

Apple Silicon 架構下的 Mac 安裝舊版 Ruby

依照以下方式進行安裝,應該就能成功為 Apple Silicon 架構下的 Mac 成功編譯出舊版 Ruby。 安裝 Ruby 使用 rvm 進行,請先自行安裝 rvm。 為了不遺留安裝過程需的環境變數於個人設定檔,我們不將環境變數寫入 Shell 設定檔, 因此每一個步驟請不要關閉終端機 session,一氣呵成做完。

第一步:安裝 OpenSSL 1.0

cd ~/Downloads
curl https://raw.githubusercontent.com/rbenv/homebrew-tap/e472b7861b49cc082d1db0f66f265368da107589/Formula/openssl%401.0.rb -o [email protected]
brew install [email protected]

# 驗證 OpenSSL 1.0 有安裝成功
/opt/homebrew/opt/[email protected]/bin/openssl version 

第二步:安裝 libffi

brew install libffi
export LDFLAGS="-L/opt/homebrew/opt/libffi/lib"
export CPPFLAGS="-I/opt/homebrew/opt/libffi/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/libffi/lib/pkgconfig"

第三步:安裝 Ruby

2.3.1 版本號替換成你想要的版本:

rvm install 2.3.1 --with-openssl-dir=/opt/homebrew/opt/[email protected]
rvm list

Ruby 2.6 版安裝法

相較於前面提到 2.4 版以前的主要問題在 OpenSSL 版本,如果要安裝較新一點的 2.6 版則會遇到另一個問題。 透過 rvm install 2.6.5 安裝時同樣會出現如下的錯誤訊息:

Error running '__rvm_make -j8',
please read /Users/yfxie/.rvm/log/1668495871_ruby-2.6.5/make.log

make.log 的關鍵錯誤訊息如下:

Undefined symbols for architecture arm64:
  "__mh_execute_header", referenced from:
      _rb_dump_backtrace_with_lines in addr2line.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如果是這種情況,需要安裝 Command Line Tools for Xcode 13.4, 安裝完成後使用以下指令切換 Command Line Tools 的版本:

sudo xcode-select -s /Library/Developer/CommandLineTools

同樣要安裝 libffi 並輸出編譯時所需的環境變數:

brew install libffi
export LDFLAGS="-L/opt/homebrew/opt/libffi/lib"
export CPPFLAGS="-I/opt/homebrew/opt/libffi/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/libffi/lib/pkgconfig"

最後運行安裝指令:

rvm install 2.6.5

成功安裝後,也將 Command Line Tools 切換回 Xcode App 的版本:

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

這樣就能成功在 Apple Silicon M1/M2 架構下的 Mac 安裝 Ruby 2.6 版了。

留言