diff options
Diffstat (limited to 'doc/contributing/building_ruby.md')
| -rw-r--r-- | doc/contributing/building_ruby.md | 137 |
1 files changed, 103 insertions, 34 deletions
diff --git a/doc/contributing/building_ruby.md b/doc/contributing/building_ruby.md index 2b7a06baba..286bd1f116 100644 --- a/doc/contributing/building_ruby.md +++ b/doc/contributing/building_ruby.md @@ -17,9 +17,12 @@ * [autoconf] - 2.67 or later * [gperf] - 3.1 or later * Usually unneeded; only if you edit some source files using gperf - * ruby - 3.0 or later + * ruby - 3.1 or later * We can upgrade this version to system ruby version of the latest Ubuntu LTS. + * git - 2.32 or later + * Anterior versions may work; 2.32 or later will prevent build + errors in case your system `.gitconfig` uses `$HOME` paths. 2. Install optional, recommended dependencies: @@ -28,12 +31,22 @@ * [rustc] - 1.58.0 or later, if you wish to build [YJIT](rdoc-ref:RubyVM::YJIT). - If you installed the libraries needed for extensions (openssl, readline, - libyaml, zlib) into other than the OS default place, typically using - Homebrew on macOS, add `--with-EXTLIB-dir` options to `CONFIGURE_ARGS` - environment variable. + 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-dir` for gmp) option to `configure`. - ``` shell + ```sh + 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-dir` + options to the command line or to `CONFIGURE_ARGS` environment variable. + The command line options will be embedded in `rbconfig.rb`, while the + latter environment variable is not embedded and is only used when + building the extension libraries. + + ```sh export CONFIGURE_ARGS="" for ext in openssl readline libyaml zlib; do CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-$ext-dir=$(brew --prefix $ext)" @@ -61,7 +74,7 @@ Download the latest tarball from [Download Ruby] page and extract it. Example for Ruby 3.0.2: - ``` shell + ```sh tar -xzf ruby-3.0.2.tar.gz cd ruby-3.0.2 ``` @@ -70,35 +83,35 @@ Checkout the CRuby source code: - ``` shell + ```sh git clone https://github.com/ruby/ruby.git cd ruby ``` - Generate the configure file: + Run the GNU Autoconf script (which generates the `configure` script): - ``` shell + ```sh ./autogen.sh ``` -2. Create a `build` directory separate from the source directory: +2. Create a `build` directory inside the repository directory: - ``` shell + ```sh mkdir build && cd build ``` - While it's not necessary to build in a separate directory, it's good + While it's not necessary to build in a dedicated directory like this, it's good practice to do so. -3. We'll install Ruby in `~/.rubies/ruby-master`, so create the directory: +3. We'll eventually install our new Ruby in `~/.rubies/ruby-master`, so we'll create that directory: - ``` shell + ```sh mkdir ~/.rubies ``` -4. Run configure: +4. Run the `configure` script (which generates the `Makefile`): - ``` shell + ```sh ../configure --prefix="${HOME}/.rubies/ruby-master" ``` @@ -107,15 +120,15 @@ 5. Build Ruby: - ``` shell + ```sh make ``` 6. [Run tests](testing_ruby.md) to confirm your build succeeded. -7. Install Ruby: +7. Install our newly-compiled Ruby into `~/.rubies/ruby-master`: - ``` shell + ```sh make install ``` @@ -123,6 +136,41 @@ generation with different permissions, you can use `make SUDO=sudo install`. +8. You can then try your new Ruby out, for example: + + ```sh + ~/.rubies/ruby-master/bin/ruby -e "puts 'Hello, World!'" + ``` + +By the end, your repo will look like this: + +```text +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 my `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 +``` + [Download Ruby]: https://www.ruby-lang.org/en/downloads/ ### Unexplainable Build Errors @@ -136,7 +184,7 @@ cause build failures. ## Building on Windows The documentation for building on Windows can be found in [the separated -file](../windows.md). +file](../distribution/windows.md). ## More details @@ -149,7 +197,7 @@ In GNU make[^caution-gmake-3] and BSD make implementations, to run a specific ma parallel, pass the flag `-j<number of processes>`. For instance, to run tests on 8 processes, use: -``` shell +```sh make test-all -j8 ``` @@ -159,7 +207,7 @@ 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: -``` shell +```sh # On macOS with Fish shell: export MAKEFLAGS="--jobs "(sysctl -n hw.ncpu) @@ -183,7 +231,7 @@ 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: -``` shell +```sh make miniruby ``` @@ -200,13 +248,37 @@ following make targets: * `make lldb-ruby`: Runs `test.rb` using Ruby in lldb * `make gdb-ruby`: Runs `test.rb` using Ruby in gdb +For VS Code users, you can set up editor-based debugging experience by running: + +```shell +cp -r misc/.vscode .vscode +``` + +This will add launch configurations for debugging Ruby itself by running `test.rb` with `lldb`. + +**Note**: if you build Ruby under the `./build` folder, you'll need to update `.vscode/launch.json`'s program entry accordingly to: `"${workspaceFolder}/build/ruby"` + ### Compiling for Debugging -You should configure Ruby without optimization and other flags that may -interfere with debugging: +You can compile Ruby with the `RUBY_DEBUG` macro to enable debugging on some +features. One example is debugging object shapes in Ruby with +`RubyVM::Shape.of(object)`. + +Additionally Ruby can be compiled to support the `RUBY_DEBUG` environment +variable to enable debugging on some features. An example is using +`RUBY_DEBUG=gc_stress` to debug GC-related issues. + +There is also support for the `RUBY_DEBUG_LOG` environment variable to log a +lot of information about what the VM is doing, via the `USE_RUBY_DEBUG_LOG` +macro. + +You should also configure Ruby without optimization and other flags that may +interfere with debugging by changing the optimization flags. + +Bringing it all together: -``` shell -./configure --enable-debug-env optflags="-O0 -fno-omit-frame-pointer" +```sh +./configure cppflags="-DRUBY_DEBUG=1 -DUSE_RUBY_DEBUG_LOG=1" --enable-debug-env optflags="-O0 -fno-omit-frame-pointer" ``` ### Building with Address Sanitizer @@ -215,7 +287,7 @@ Using the address sanitizer (ASAN) is a great way to detect memory issues. It can detect memory safety issues in Ruby itself, and also in any C extensions compiled with and loaded into a Ruby compiled with ASAN. -``` shell +```sh ./autogen.sh mkdir build && cd build ../configure CC=clang-18 cflags="-fsanitize=address -fno-omit-frame-pointer -DUSE_MN_THREADS=0" # and any other options you might like @@ -229,15 +301,12 @@ two hours on my laptop); the `RUBY_TEST_TIMEOUT_SCALE` and `SYNTAX_SUGEST_TIMEOUT` variables are required to make sure tests don't spuriously fail with timeouts when in fact they're just slow. -``` shell +```sh RUBY_TEST_TIMEOUT_SCALE=5 SYNTAX_SUGGEST_TIMEOUT=600 make check ``` Please note, however, the following caveats! -* ASAN will not work properly on any currently released version of Ruby; the - necessary support is currently only present on Ruby's master branch (and the - whole test suite passes only as of commit [Revision 9d0a5148]). * Due to [Bug #20243], Clang generates code for threadlocal variables which doesn't work with M:N threading. Thus, it's necessary to disable M:N threading support at build time for now (with the `-DUSE_MN_THREADS=0` @@ -264,7 +333,7 @@ Please note, however, the following caveats! You need to be able to use gcc (gcov) and lcov visualizer. -``` shell +```sh ./autogen.sh ./configure --enable-gcov make |
