Skip to content
Mislav Marohnić edited this page Aug 27, 2024 · 200 revisions

ruby-build is a tool that downloads and compiles various versions of Ruby. It is exposed as rbenv install through rbenv or simply as ruby-build when used standalone.

Suggested build environment

ruby-build will try its best to download and compile the wanted Ruby version, but sometimes compilation fails because of unmet system dependencies, or compilation succeeds but the new Ruby version exhibits weird failures at runtime. The following instructions are our recommendations for a reasonable build environment.

macOS

We recommend using Homebrew to manage installing packages on macOS.

# install Xcode Command Line Tools
xcode-select --install
# install dependencies with Homebrew
brew install openssl@3 readline libyaml gmp

It is no longer necessary to set RUBY_CONFIGURE_OPTS to explicitly link to Homebrew OpenSSL, since ruby-build will now automatically detect and link to a compatible OpenSSL version.

Ruby 3.0 or older versions need OpenSSL 1.1 instead of OpenSSL 3. (Note that these Ruby versions are now unsupported upstream and might experience other build failures depending on OS and CPU architecture combinations.)

# only for Ruby 3.0, 2.7, or older
brew install [email protected]

Ruby 3.2 and above requires the Rust compiler if you want to have YJIT enabled:

brew install rust
ruby-build 3.2.2 /opt/rubies/ruby-3.2.2 -- --enable-yjit

Ubuntu/Debian/Mint

apt-get install autoconf patch build-essential rustc libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev

Depending on your OS version, libgdbm6 won't be available. In that case, try an earlier version, such as libgdbm5.

RHEL/CentOS

yum install -y autoconf gcc patch bzip2 openssl-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel tar

If you want to use YJIT, you need to use after RHEL8 and install rust.

yum install -y rust

Fedora

dnf install -y autoconf gcc rust patch make bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel

FreeBSD

pkg install devel/autoconf devel/bison devel/patch lang/gcc lang/rust databases/gdbm devel/gmake devel/libffi textproc/libyaml devel/ncurses security/openssl devel/readline

openSUSE

zypper install -y gcc make rust patch automake bzip2 libopenssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel

Arch Linux

pacman -S --needed base-devel rust libffi libyaml openssl zlib

If needed, install gcc6 from the AUR.

Alpine Linux

apk add build-base gcc6 patch bzip2 libffi-dev openssl-dev ncurses-dev gdbm-dev zlib-dev readline-dev yaml-dev

If you plan to use YJIT, the rust package will also be required

apk add rust

Updating ruby-build

If you have trouble installing a Ruby version, first try to update ruby-build to get the latest bug fixes and Ruby definitions.

First locate it on your system:

which ruby-build
ls "$(rbenv root)"/plugins

If it's in /opt/homebrew/bin or /usr/local/bin on a Mac, you've probably installed it via Homebrew:

brew upgrade ruby-build

Or, if you have it installed via git as an rbenv plugin:

git -C "$(rbenv root)"/plugins/ruby-build pull

Troubleshooting

For more troubleshooting tips, check the Discussions section.

Missing OpenSSL

The Ruby openssl extension was not compiled. Missing the OpenSSL lib?

You may need to install openssl development headers:

  • Ubuntu: apt-get install libssl-dev
  • Fedora: yum install openssl-devel
  • Void Linux: xbps-install -Su openssl-devel
  • Homebrew: brew install openssl@3

Note

Keep in mind that ruby-build tries to detect an OpenSSL version already installed on the system and, failing that, it automatically downloads and installs a version of OpenSSL exclusively for use with Ruby. Therefore, the fact that a system OpenSSL version is missing should not be a blocker for installing Ruby with ruby-build. The Missing the OpenSSL lib? error message, however, might be an indicator that something else went wrong when trying to link to an existing OpenSSL version.

If installing these extra packages did not help, something else might have caused Ruby's openssl extension to fail while compiling, but often there will not be any further information in ruby-build's log about this.

To look into the build log for the openssl extension specifically, take a note of the build directory named in Inspect or clean up the working tree at <DIR> of ruby-build's output, then find the ruby-*/ext/openssl/mkmf.log file there.

If you have multiple OpenSSL versions installed on the system, it might help to pick one explicitly:

ruby-build <version> <destination> -- --with-openssl-dir="$(brew --prefix openssl@3)"

Ruby 3.1.x on Apple Silicon

Some macOS users on M1 laptops have experienced the following failures:

dyld: could not load inserted library
...
incompatible architecture (have 'arm64', need 'arm64e')

See this discussion for workarounds.

C compiler cannot create executables

There can be different causes of this error and none of them are usually immediately apparent. However, often the cause is that the build environment is incomplete or broken. Make sure you first follow the instructions in Suggested build environment.

Having the Anaconda set of Python tools is known to cause issues with building Ruby. The only know solution so far is to uninstall Anaconda.

mkdir: /Volumes/Macintosh: Not a directory

This can occur if you have more than one disk drive and your home directory is physically mounted on a volume that might have a space in its name, such as Macintosh HD:

$ df
/dev/disk2    ...  /
/dev/disk1s2  ...  /Volumes/Macintosh HD

The easiest solution is to avoid building a Ruby version to any path that has space characters in it. So instead of building into ~/.rbenv/versions/<version>, which is the default for rbenv install <version>, instead you could install into /opt/rubies/<version> and symlink /opt/rubies as ~/.rbenv/versions so rbenv continues to work as before.

Arch Linux default gem install path

WARNING:  You don't have ${HOME}/.gem/ruby/1.8/bin in your PATH,
          gem executables will not run.

The system Ruby creates the /etc/gemrc file which contains --user-install by default so that pacman-managed gems are not mixed up with externally installed gems. This setting affects the gem command in all Ruby versions, so all gems will get installed under ~/.gem instead of the default install path $(rbenv prefix)/lib/ruby/gems.

This is not a problem for ruby-build, but rbenv doesn't play well with --user-install, since it can't discover gem executables that were placed under ~/.gem.

No space left on device

Some distributions will mount a tmpfs partition with low disk space to /tmp, such as 250 MB. You can check this with:

mount | grep tmp
df -h | grep tmp

Compiling MRI requires at least 265 MB, so you should temporarily resize /tmp to allow more usage:

rm -rf /tmp/ruby-build*
mount -o remount,size=300M,noatime /tmp

Cannot load such file -- auto_gem

Gentoo defines a system-wide RUBYOPT environment variable that automatically wants to load auto_gem whenever any Ruby scripts gets executed. This will fail for Ruby versions other than the system one.

$ cat /etc/env.d/10rubygems
RUBYOPT="-rauto_gem"

The solution is to configure your shell init script to export -n RUBYOPT (unexport) the value from your environment.

gcc: internal compiler error: Killed

Machines that report a large amount of CPU cores but not enough RAM might experience this error when compiling.

Use MAKE_OPTS to lower the number of parallel processes:

MAKE_OPTS=-j2 ruby-build ...