构建 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 进行构建

使用地址清理程序是检测内存问题的好方法。

./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 运行。如果要测量一次测试运行,请确保删除该文件。

您可以在 rubyci.org/coverage 上查看 CI 的覆盖率结果