Building Ruby
Dependencies
-
Install the prerequisite dependencies for building the CRuby interpreter:
-
C compiler
For RubyGems, you will also need:
If you want to build from the git repository, you will also need:
-
autoconf - 2.67 or later
-
gperf - 3.1 or later
-
Usually unneeded; only if you edit some source files using gperf
-
-
ruby - 3.1 or later
-
We can upgrade this version to system ruby version of the latest Ubuntu LTS.
-
-
git - 2.32 or later
-
Earlier versions may work; 2.32 or later will prevent build errors in case your system
.gitconfiguses$HOMEpaths.
-
-
-
Install optional, recommended dependencies:
If you want to link the libraries (e.g., gmp) installed into other than the OS default place, typically using Homebrew on macOS, pass the
--with-opt-dir(or--with-gmp-dirfor gmp) option toconfigure.configure --with-opt-dir=$(brew --prefix gmp):$(brew --prefix jemalloc)
As for the libraries needed for particular extensions only and not for Ruby (openssl, readline, libyaml, zlib), you can add
--with-EXTLIB-diroptions to the command line or toCONFIGURE_ARGSenvironment variable. The command line options will be embedded inrbconfig.rb, while the latter environment variable is not embedded and is only used when building the extension libraries.export CONFIGURE_ARGS="" for ext in openssl readline libyaml zlib; do CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-$ext-dir=$(brew --prefix $ext)" done
Quick start guide
-
Download ruby source code:
Select one of the below.
-
Build from the tarball:
Download the latest tarball from Download Ruby page and extract it. Example for Ruby 3.0.2:
tar -xzf ruby-3.0.2.tar.gz cd ruby-3.0.2
-
Build from the git repository:
Checkout the CRuby source code:
git clone https://github.com/ruby/ruby.git cd ruby
Run the GNU Autoconf script (which generates the
configurescript):./autogen.sh
-
-
Create a
builddirectory inside the repository directory:mkdir build && cd build
While it's not necessary to build in a dedicated directory like this, it's good practice to do so.
-
We'll eventually install our new Ruby in
~/.rubies/ruby-master, so we'll create that directory:mkdir ~/.rubies
-
Run the
configurescript (which generates theMakefile):../configure --prefix="${HOME}/.rubies/ruby-master"-
Also
-C(or--config-cache) would reduce time to configure from the next time.
-
-
Build Ruby:
make
-
Run tests to confirm your build succeeded.
-
Install our newly-compiled Ruby into
~/.rubies/ruby-master:make install
-
If you need to run
make installwithsudoand want to avoid document generation with different permissions, you can usemake SUDO=sudo install.
-
-
You can then try your new Ruby out, for example:
~/.rubies/ruby-master/bin/ruby -e "puts 'Hello, World!'"
By the end, your repo will look like this:
ruby βββ autogen.sh # Pre-existing Autoconf script, used in step 1 βββ configure # Generated in step 1, which generates the `Makefile` in step 4 βββ build # Created in step 2 and populated in step 4 β βββ GNUmakefile # Generated by `../configure` β βββ Makefile # Generated by `../configure` β βββ object.o # Compiled object file, built by `make` β βββ ... other compiled `.o` object files β β # Other interesting files: βββ include β βββ ruby.h # The main public header βββ internal β βββ object.h β βββ ... other header files used by the `.c` files in the repo root. βββ lib β βββ # Default gems, like `bundler`, `erb`, `set`, `yaml`, etc. βββ spec β βββ # A mirror of the Ruby specification from github.com/ruby/spec βββ test β βββ ruby β βββ ... βββ object.c βββ ... other `.c` files
Unexplainable Build Errors
If you are having unexplainable build errors, after saving all your work, try running git clean -xfd in the source root to remove all git ignored local files. If you are working from a source directory thatβs been updated several times, you may have temporary build artifacts from previous releases which can cause build failures.
Building on Windows
The documentation for building on Windows can be found in the separated file.
More details
If youβre interested in continuing development on Ruby, here are more details about Rubyβs build to help out.
Running make scripts in parallel
In GNU make1 and BSD make implementations, to run a specific make script in parallel, pass the flag -j<number of processes>. For instance, to run tests on 8 processes, use:
make test-all -j8
We can also set MAKEFLAGS to run all make commands in parallel.
Having the right --jobs flag will ensure all processors are utilized when building software projects. To do this effectively, you can set MAKEFLAGS in your shell configuration/profile:
# 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 vs Ruby
Miniruby is a version of Ruby which has no external dependencies and lacks certain features. It can be useful in Ruby development because it allows for faster build times. Miniruby is built before Ruby. A functional Miniruby is required to build Ruby. To build Miniruby:
make miniruby
Statically linking extensions
configure --with-static-linked-ext links the extension libraries under ext/ into the ruby binary instead of building them as separate .so/.bundle files, and makes RbConfig::CONFIG["EXTSTATIC"] "static". Bundled gems that have C extensions, such as bigdecimal and fiddle, are unaffected and are still built as loadable objects.
The external libraries the extensions need are then linked into ruby itself, so pass --with-EXTLIB-dir to configure rather than putting the paths in LDFLAGS by hand. On macOS with Homebrew:
./configure --with-static-linked-ext --with-openssl-dir=$(brew --prefix openssl@3)
brew --prefix LIB prints a path even for a formula that is not installed, so generating LDFLAGS from it can yield -L options for directories that do not exist, which configure rejects. Use brew --prefix --installed LIB, which fails instead of printing a path for an uninstalled formula.
Debugging
See Debugging Ruby.
How to measure coverage of C and Ruby code
You need to be able to use gcc (gcov) and lcov visualizer.
./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
If you need only C code coverage, you can remove COVERAGE=true from the above process. You can also use gcov command directly to get per-file coverage.
If you need only Ruby code coverage, you can remove --enable-gcov. Note that test-coverage.dat accumulates all runs of make test-all. Make sure that you remove the file if you want to measure one test run.
You can see the coverage result of CI: rubyci.org/coverage
1 CAUTION: GNU make 3 is missing some features for parallel execution, we recommend to upgrade to GNU make 4 or later.