Open-Source Wikis

/

Ruby

/

Build system

ruby/ruby

Build system

CRuby's build is autoconf + make, supplemented by a substantial Ruby-driven code-generation pipeline. The chain is:

  1. autogen.sh runs autoconf to regenerate configure from configure.ac.
  2. ./configure probes the platform and emits Makefile, config.h, verconf.h.
  3. make builds miniruby (a bootstrap interpreter), then uses it to drive Ruby-based code generators (the parser, instruction dispatch, transcoding tables, etc.), then builds the full ruby binary plus all enabled C extensions and Rust JITs.
graph TD
    autogen[autogen.sh: autoconf] --> configure[configure script]
    configure --> probe[Probe platform: headers, libs, types]
    probe --> Makefile[Makefile + config.h + verconf.h]
    Makefile --> mini[Build miniruby]
    mini --> srcs[make srcs: run Ruby code generators]
    srcs --> parser[parse.c via Lrama]
    srcs --> insns[vm_exec.c via tool/ruby_vm/]
    srcs --> trans[enc/trans/*.c via transcode-tblgen]
    srcs --> builtin[*.rbinc via mk_builtin_loader.rb]
    Makefile --> rust[Build YJIT/ZJIT crates via cargo]
    Makefile --> exts[Build ext/*/*.so via tool/extmk.rb]
    Makefile --> ruby[Link ruby binary]

Pages in this section

Outputs after make

  • ./miniruby — the bootstrap interpreter. Statically linked; no extensions; can run Ruby-implemented build helpers.
  • ./ruby — the full interpreter binary.
  • ./libruby.so (with --enable-shared) — shared library form of the interpreter.
  • ./<ext>.so — built C extensions for in-tree testing.
  • ./revision.h, ./verconf.h, ./config.h — generated headers.
  • ./parse.c, ./vm_exec.c, etc. — generated source files.

After make install

The install layout (under <prefix>):

<prefix>/
├── bin/
│   ├── ruby            # main binary
│   ├── irb             # interactive Ruby
│   ├── erb             # embedded Ruby templating CLI
│   ├── gem             # RubyGems CLI
│   ├── bundle          # Bundler CLI
│   └── rake            # Rake CLI
├── lib/
│   └── ruby/
│       ├── <api-ver>/                 # stdlib (default gems)
│       ├── site_ruby/<api-ver>/       # local additions
│       ├── vendor_ruby/<api-ver>/     # OS distribution additions
│       └── gems/<api-ver>/            # installed gems
├── include/
│   └── ruby-<api-ver>/<arch>/         # public headers
└── share/
    ├── doc/ruby-<ver>/                # rdoc-generated docs (unless --disable-install-doc)
    └── man/man1/ruby.1                # manpage

Common build commands

Command What it does
./autogen.sh Regenerate configure from configure.ac
./configure --prefix=... Probe + generate Makefile
make Full build: miniruby → srcs → ruby + extensions + JITs
make srcs Just regenerate generated source files
make miniruby Just rebuild miniruby
make (incremental) Rebuild only what changed
make install Install to --prefix
make install-nodoc Install without RDoc generation (faster)
make check Build + run all tests
make exam check + lint + leak checks
make run Quick run via tool/runruby.rb
make benchmark Run a curated benchmark subset
make update-deps Regenerate depend files
make update-bundled_gems Refresh gems/bundled_gems
make distclean Wipe build artefacts

Cross-platform builds

CRuby supports Windows (MSVC + MinGW), macOS, Linux, BSDs, Solaris, AIX, and several embedded targets. Cross-compilation to WASM is supported via --target=wasm32-wasi and the toolchain in wasm/.

.github/workflows/ shows the matrix:

  • Ubuntu 22/24 with GCC, Clang, with/without YJIT/ZJIT/MMTk
  • macOS (latest)
  • Windows MSVC and MinGW
  • Free/NetBSD via QEMU
  • WASI via WASI-SDK

Build-time code generation

A substantial fraction of "source" files are generated. Generators run during make srcs:

Output Generator Input
parse.c tool/lrama/ parse.y
vm_exec.c, vmtc.inc tool/ruby_vm/ insns.def
*.rbinc tool/mk_builtin_loader.rb *.rb files (array.rb, etc.)
enc/trans/*.c tool/transcode-tblgen.rb enc/trans/*.trans
enc/unicode/data/* tool/enc-unicode.rb Unicode UCD
revision.h tool/file2lastrev.rb git history
prism/prism.c (parts) prism/templates/template.rb prism/config.yml
id.h, id.c tool/id2token.rb tokens

Editing one of these output files directly is futile — the next make srcs will overwrite it.

Bootstrap problem

CRuby is implemented in C, but its build needs Ruby — to run Lrama, the VM-instruction generators, and many other tools. To resolve this:

  1. The build needs a base Ruby (BASERUBY). configure searches for an existing ruby/rbenv/rvm install.
  2. If no system Ruby is available, the build can fall back to a stub (tool/missing-baseruby.bat) that errors with a helpful message.
  3. The first product of the build is miniruby — once it exists, BASERUBY is no longer needed; subsequent code generation runs on miniruby.

miniruby is statically linked and intentionally minimal — no encoding tables loaded, no extensions, no gems. It exists solely to bootstrap the rest of the build.

Rust integration

Cargo.toml at the repo root is a workspace with members yjit, zjit, and jit. The Rust crates are built into static libraries that are linked into ruby:

  • yjit/yjit.mk and zjit/zjit.mk are included from the main Makefile.
  • They invoke cargo directly with the right --target and --profile.
  • The output libyjit.a / libzjit.a is linked into the final ruby binary.

Cargo.toml declares the JIT features as optional so building without --enable-yjit/--enable-zjit doesn't require Rust at all. Release builds avoid Cargo for the offline-build property: rustc is invoked directly with prebuilt deps.

Extension building

tool/extmk.rb walks ext/ and runs each extension's build:

  1. Run extconf.rb (which uses mkmf) to detect dependencies and emit a Makefile.
  2. Run make in that directory to build <ext>.so.
  3. Copy/link the resulting .so into ./ruby's search path for in-tree testing.

make install then installs the .sos into <prefix>/lib/ruby/<api-ver>/<arch>/.

Configuring out a feature

Many features can be disabled at configure time:

./configure --disable-shared            # static libruby.a, no .so
./configure --disable-install-rdoc      # no rdoc generation (fast)
./configure --disable-yjit              # exclude YJIT
./configure --disable-zjit              # exclude ZJIT
./configure --without-ext=socket,psych  # exclude specific extensions
./configure --disable-jit-support       # exclude all JITs

See configure.md for the full flag list and probes.

See build/makefile.md for the Makefile targets in detail.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Build system – Ruby wiki | Factory