Open-Source Wikis

/

Ruby

/

Build system

/

Makefile

ruby/ruby

Makefile

After ./configure, the top-level Makefile is generated from Makefile.in + common.mk + platform-specific *.mk includes. common.mk (~74,000 bytes) is the platform-independent body where most of the actual rules live.

Top-level structure

Makefile
├── Generated header (paths, platform variables)
├── @MAKEFILE_INCLUDES@         (common.mk, platform .mk files)
├── User overrides + fix-up rules
└── Auto-included dependency lists (depend, ext/*/depend)

Phases of make

A from-scratch make runs through several phases:

graph LR
    miniruby[1. miniruby] --> srcs[2. make srcs]
    srcs --> ruby[3. ruby]
    srcs --> exts[4. extensions]
    srcs --> rust[5. rust crates]
    ruby --> link[6. final link]
    exts --> link
    rust --> link
  1. miniruby: build the bootstrap interpreter. This requires BASERUBY (a pre-existing Ruby) only for parsing the build's own Ruby tools.
  2. srcs: run code generators (Lrama, ruby_vm/, transcode-tblgen, mk_builtin_loader, prism templates) using miniruby (or BASERUBY if miniruby isn't ready yet for some specific tool).
  3. ruby: link the full interpreter from the C objects (~200+ .o files) plus the encoding objects.
  4. extensions: tool/extmk.rb runs each ext/*/extconf.rb and builds each extension's .so.
  5. rust crates: cargo build for yjit/ and zjit/ (if enabled), producing static libraries.
  6. final link: tie everything together into the production ./ruby binary.

make -j N parallelises within each phase. The phases themselves are mostly serial (extensions can't link until ruby is built; ruby can't link until srcs is done).

Major targets

Build targets

Target What it does
make all (default) Full build: miniruby + srcs + ruby + extensions + JITs
make miniruby Just ./miniruby
make ruby The full ./ruby (assumes srcs is current)
make srcs Run all code generators
make showflags Print the current compile/link flags
make extract-extlibs Run tool/extlibs.rb to fetch optional C libraries
make showconfig Dump configure-derived variables

Test targets

Target What it does
make btest Run bootstraptest/
make test-basic Run basictest/
make test-all Run test/ (test-unit)
make test-spec Run spec/ruby/ (MSpec)
make check All of the above
make exam check + leaked-globals + lint
make test-spec MSPECOPT=... Pass options to MSpec
make test-all TESTS=... Pass options to test runner
make test-rubyspec Alias for test-spec

Install targets

Target What it does
make install Install to --prefix
make install-nodoc Install without rdoc (much faster)
make uninstall Remove installed files

Maintenance targets

Target What it does
make update-deps Regenerate per-file dependency lists in depend
make update-mailmap Regenerate .mailmap from authors
make update-bundled_gems Refresh gems/bundled_gems
make sync-default-gems-all Pull all default gems from upstream
make sync-default-gems-X Pull a specific default gem
make update-coverage Run coverage reporting
make leaked-globals Check the binary for leaked global symbols

Cleanup targets

Target What it does
make clean Remove built object files (keeps Makefile)
make distclean clean + remove Makefile, configure outputs
make realclean distclean + remove configure (ready for autogen.sh)
make ext/<name>/clean Clean one extension

Run helpers

Target What it does
make run Quick run via tool/runruby.rb (uses RUNOPT="...")
make runruby Same
make benchmark Run a curated benchmark subset

Per-extension builds

The ext/<name>/ subdirectory has its own Makefile (generated by extconf.rb). The top-level Makefile recurses into each via tool/extmk.rb. To rebuild just one extension:

cd ext/socket
make clean
make

This is faster than a full top-level rebuild after changing one extension.

Generated dependency files

Most of the heavy lifting in common.mk is per-file dependency lists, allowing parallel builds. These live in:

  • depend — top-level. ~1.1 MB (every C file's full include graph).
  • ext/<name>/depend — per-extension.
  • enc/depend, enc/trans/depend — encoding tables.

make update-deps regenerates these by running tool/update-deps. After editing C headers, run make update-deps so make knows what to rebuild.

Parallelism

make -j$(nproc) works for most builds. Some targets (like make test-all) parallelise internally; passing -j to them is harmless but slower than the runner's own parallelism.

make -j N TESTRUN_OPTS="--jobs=N" for parallel test runs.

Variables you might pass

Variable Purpose
OPTS=... Pass arbitrary options to the test runner
TESTS=... Specific tests to run (make test-all TESTS=...)
MSPECOPT=... Specific MSpec options
BTESTS=... Specific bootstrap tests
RUNOPT=... Args for make run
BENCH_RUBY=... Override ruby for benchmarks
BENCH_FILE=... Specific benchmark file
OPTFLAGS=..., DEBUGFLAGS=... Override per-build optimisation/debug flags
V=1 Verbose output (show full commands)

Incremental rebuild behaviour

After an initial make:

  • Editing compile.c → rebuild compile.o and re-link ruby. ~10 seconds.
  • Editing parse.y → re-run Lrama, rebuild parse.o, re-link. ~30 seconds.
  • Editing insns.def → re-run tool/ruby_vm/, rebuild many vm_*.o, re-link. ~1 minute.
  • Editing array.rb → re-run mk_builtin_loader.rb, rebuild array.o, re-link. ~5 seconds.
  • Editing Cargo.toml → re-run cargo, re-link. ~30 seconds (+ the Rust compile time).

Failure modes

Symptom Likely cause
make: *** No rule to make target ... Stale depend. Run make update-deps.
Configure-derived variable wrong Edit and re-run ./config.status --recheck.
Linker errors after pulling new code make distclean && ./configure ... && make — header sizes may have changed.
cargo errors Check Cargo.toml's rust-version requirement. Update toolchain or pass RUSTFLAGS.
extconf.rb failure Check mkmf.log in the offending extension dir.

Editing common.mk

common.mk is the canonical body. Variants (win32/Makefile.sub, cygwin/GNUmakefile.in) override platform-specific bits.

When adding a new top-level source file:

  1. Edit common.mk to register it in OBJ.
  2. Run make update-deps to add its dependency list to depend.
  3. Run make and verify it builds.

When adding a new tool to tool/:

  1. Add a Make rule in common.mk that invokes it via BASERUBY or MINIRUBY.
  2. Wire it into srcs: if it generates source files.

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

Makefile – Ruby wiki | Factory