編譯 Ruby

相依性

  1. 安裝編譯 CRuby 詮釋器的必要相依性

    • C 編譯器

    對於 RubyGems,您還需要

    • OpenSSL 1.1.x 或 3.0.x / LibreSSL

    • libyaml 0.1.7 或更新版本

    • zlib

    如果您想從 git 儲存庫編譯,您還需要

    • autoconf - 2.67 或更新版本

    • gperf - 3.1 或更新版本

      • 通常不需要;只有在您使用 gperf 編輯某些原始檔時才需要

    • ruby - 2.5 或更新版本

      • 我們可以將此版本升級到最新 Ubuntu LTS 的系統 ruby 版本。

  2. 安裝可選的建議相依性

    • libffi(編譯 fiddle)

    • gmp(如果你想加速 Bignum 運算)

    • libexecinfo(FreeBSD)

    • rustc - 1.58.0 或更新版本,如果你想建置 YJIT

    如果你將延伸模組所需的函式庫(openssl、readline、libyaml、zlib)安裝在作業系統預設位置以外的地方(通常在 macOS 上使用 Homebrew),請將 --with-EXTLIB-dir 選項新增到 CONFIGURE_ARGS 環境變數。

    export CONFIGURE_ARGS=""
    for ext in openssl readline libyaml zlib; do
      CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-$ext-dir=$(brew --prefix $ext)"
    done

快速入門指南

  1. 下載 Ruby 原始碼

    選擇下列其中一項。

    1. 從 tarball 建置

      ruby-lang.org 下載最新的 tarball 並解壓縮。Ruby 3.0.2 的範例

      tar -xzf ruby-3.0.2.tar.gz
      cd ruby-3.0.2
    2. 從 git 儲存庫建置

      簽出 CRuby 原始碼

      git clone https://github.com/ruby/ruby.git
      cd ruby

      產生設定檔

      ./autogen.sh
  2. 建立一個與原始碼目錄分開的 build 目錄

    mkdir build && cd build

    雖然在分開的目錄中建置並非必要,但這是一個好習慣。

  3. 我們將在 ~/.rubies/ruby-master 中安裝 Ruby,因此建立目錄

    mkdir ~/.rubies
  4. 執行設定

    ../configure --prefix="${HOME}/.rubies/ruby-master"
    • 如果你經常建置 Ruby,請新增 --disable-install-doc 旗標,以不建置文件,這將加速建置程序。

    • 此外,-C(或 --config-cache)會減少下次設定的時間。

  5. 建置 Ruby

    make install
    
  6. 執行測試以確認你的建置成功。

無法解釋的建置錯誤

如果你遇到無法解釋的建置錯誤,在儲存所有工作後,請嘗試在原始碼根目錄中執行 git clean -xfd 以移除所有 git 忽略的本機檔案。如果你從已更新多次的原始碼目錄中工作,你可能會有來自先前版本的暫時建置產出,這可能會導致建置失敗。

在 Windows 上建置

可以在 這裡 找到在 Windows 上建置的文件。

更多詳細資訊

如果你有興趣繼續開發 Ruby,這裡有更多關於 Ruby 建置的詳細資訊以提供協助。

並行執行 make 腳本

在 GNU make 和 BSD make 實作中,若要並行執行特定的 make 腳本,請傳遞旗標 -j<處理程序數目>。例如,若要在 8 個處理程序上執行測試,請使用

make test-all -j8

我們也可以設定 MAKEFLAGS 以並行執行所有 make 指令。

擁有正確的 --jobs 旗標將確保在建置軟體專案時,所有處理器都能被使用。若要有效執行此動作,您可以在 shell 組態/設定檔中設定 MAKEFLAGS

# On macOS with Fish shell:
export MAKEFLAGS="--jobs "(sysctl -n hw.ncpu)

# On macOS with Bash/ZSH shell:
export MAKEFLAGS="--jobs $(sysctl -n hw.ncpu)"

# On Linux with Fish shell:
export MAKEFLAGS="--jobs "(nproc)

# On Linux with Bash/ZSH shell:
export MAKEFLAGS="--jobs $(nproc)"

Miniruby 與 Ruby

Miniruby 是 Ruby 的版本,沒有外部相依性,並缺乏某些功能。它在 Ruby 開發中很有用,因為它能讓建置時間更快。Miniruby 是在 Ruby 之前建置的。建置 Ruby 需要一個可運作的 Miniruby。若要建置 Miniruby

make miniruby

除錯

您可以使用 lldb 或 gdb 進行除錯。在除錯之前,您需要使用您想執行的 Ruby 腳本建立一個 test.rb。您可以使用以下 make 目標

編譯以進行除錯

您應該在沒有最佳化和其他可能干擾除錯的旗標的情況下設定 Ruby

./configure --enable-debug-env optflags="-O0 -fno-omit-frame-pointer"

使用 Address Sanitizer 建置

使用 Address Sanitizer 是偵測記憶體問題的好方法。

./autogen.sh
mkdir build && cd build
export ASAN_OPTIONS="halt_on_error=0:use_sigaltstack=0:detect_leaks=0"
../configure cppflags="-fsanitize=address -fno-omit-frame-pointer" optflags=-O0 LDFLAGS="-fsanitize=address -fno-omit-frame-pointer"
make

在 Linux 上,在除錯時指定 -O0 很重要。這對於 ASAN 尤其如此,因為它有時會在較高的最佳化層級下不正確地運作。

如何測量 C 和 Ruby 程式碼的涵蓋率

您需要能夠使用 gcc (gcov) 和 lcov 視覺化工具。

./autogen.sh
./configure --enable-gcov
make
make update-coverage
rm -f test-coverage.dat
make test-all COVERAGE=true
make lcov
open lcov-out/index.html

如果您只需要 C 程式碼涵蓋率,您可以從上述流程中移除 COVERAGE=true。您也可以直接使用 gcov 指令來取得每個檔案的涵蓋率。

如果您只需要 Ruby 程式碼涵蓋率,您可以移除 --enable-gcov。請注意,test-coverage.dat 會累積所有 make test-all 的執行。如果您想要測量一次測試執行,請務必移除該檔案。

您可以在 CI 中看到涵蓋率結果:rubyci.org/coverage