diff --git a/doc/contributing/building_ruby.md b/doc/contributing/building_ruby.md index 304bbee37f..832b3687fa 100644 --- a/doc/contributing/building_ruby.md +++ b/doc/contributing/building_ruby.md @@ -18,7 +18,8 @@ * gperf - 3.1 or later * Usually unneeded; only if you edit some source files using gperf * ruby - 3.0 or later - * We can upgrade this version to system ruby version of the latest Ubuntu LTS. + * We can upgrade this version to system ruby version of the latest + Ubuntu LTS. 2. Install optional, recommended dependencies: @@ -28,8 +29,10 @@ * rustc - 1.58.0 or later, if you wish to build [YJIT](https://docs.ruby-lang.org/en/master/RubyVM/YJIT.html). - 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 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. ``` shell export CONFIGURE_ARGS="" @@ -46,8 +49,9 @@ 1. Build from the tarball: - Download the latest tarball from [ruby-lang.org](https://www.ruby-lang.org/en/downloads/) and - extract it. Example for Ruby 3.0.2: + Download the latest tarball from + [ruby-lang.org](https://www.ruby-lang.org/en/downloads/) and extract + it. Example for Ruby 3.0.2: ``` shell tar -xzf ruby-3.0.2.tar.gz @@ -75,7 +79,8 @@ mkdir build && cd build ``` - While it's not necessary to build in a separate directory, it's good practice to do so. + While it's not necessary to build in a separate directory, it's good + practice to do so. 3. We'll install Ruby in `~/.rubies/ruby-master`, so create the directory: @@ -89,7 +94,8 @@ ../configure --prefix="${HOME}/.rubies/ruby-master" ``` - - Also `-C` (or `--config-cache`) would reduce time to configure from the next time. + - Also `-C` (or `--config-cache`) would reduce time to configure from the + next time. 5. Build Ruby: @@ -105,12 +111,17 @@ make install ``` - - If you need to run `make install` with `sudo` and want to avoid document generation with different permissions, you can use - `make SUDO=sudo install`. + - If you need to run `make install` with `sudo` and want to avoid document + generation with different permissions, you can use `make SUDO=sudo + install`. ### 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. +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 @@ -123,8 +134,9 @@ about Ruby's build to help out. ### Running make scripts in parallel -In GNU make and BSD make implementations, to run a specific make script in parallel, pass the flag `-j`. For instance, -to run tests on 8 processes, use: +In GNU make and BSD make implementations, to run a specific make script in +parallel, pass the flag `-j`. For instance, to run tests +on 8 processes, use: ``` shell make test-all -j8 @@ -135,7 +147,9 @@ recommend to upgrade to GNU make 4 or later. 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: +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 # On macOS with Fish shell: @@ -153,9 +167,10 @@ 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: +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: ``` shell make miniruby @@ -163,8 +178,9 @@ make miniruby ## Debugging -You can use either lldb or gdb for debugging. Before debugging, you need to create a `test.rb` -with the Ruby script you'd like to run. You can use the following make targets: +You can use either lldb or gdb for debugging. Before debugging, you need to +create a `test.rb` with the Ruby script you'd like to run. You can use the +following make targets: * `make run`: Runs `test.rb` using Miniruby * `make lldb`: Runs `test.rb` using Miniruby in lldb @@ -175,7 +191,8 @@ with the Ruby script you'd like to run. You can use the following make targets: ### Compiling for Debugging -You should configure Ruby without optimization and other flags that may interfere with debugging: +You should configure Ruby without optimization and other flags that may +interfere with debugging: ``` shell ./configure --enable-debug-env optflags="-O0 -fno-omit-frame-pointer" @@ -183,7 +200,9 @@ You should configure Ruby without optimization and other flags that may interfer ### Building with Address Sanitizer -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. +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 ./autogen.sh @@ -191,7 +210,13 @@ 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 make ``` -The compiled Ruby will now automatically crash with a report and a backtrace if ASAN detects a memory safety issue. To run Ruby's test suite under ASAN, issue the following command. Note that this will take quite a long time (over 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. + +The compiled Ruby will now automatically crash with a report and a backtrace +if ASAN detects a memory safety issue. To run Ruby's test suite under ASAN, +issue the following command. Note that this will take quite a long time (over +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 RUBY_TEST_TIMEOUT_SCALE=5 SYNTAX_SUGGEST_TIMEOUT=600 make check @@ -199,11 +224,28 @@ 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 [9d0a5148ae062a0481a4a18fbeb9cfd01dc10428](https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/9d0a5148ae062a0481a4a18fbeb9cfd01dc10428)) -* Due to [this bug](https://bugs.ruby-lang.org/issues/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` configure argument). -* ASAN will only work when using Clang version 18 or later - it requires [this bugfix](https://github.com/llvm/llvm-project/pull/75290) related to multithreaded `fork`. -* ASAN has only been tested so far with Clang on Linux. It may or may not work with other compilers or on other platforms - please file an issue on [https://bugs.ruby-lang.org](https://bugs.ruby-lang.org) if you run into problems with such configurations (or, to report that they actually work properly!) -* In particular, although I have not yet tried it, I have reason to believe ASAN will _not_ work properly on macOS yet - the fix for the multithreaded fork issue was actually reverted for macOS (see [here](https://github.com/llvm/llvm-project/commit/2a03854e4ce9bb1bcd79a211063bc63c4657f92c)). Please open an issue on [https://bugs.ruby-lang.org](https://bugs.ruby-lang.org) if this is a problem for you. +* 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 + [9d0a5148ae062a0481a4a18fbeb9cfd01dc10428](https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/9d0a5148ae062a0481a4a18fbeb9cfd01dc10428)) +* Due to [this bug](https://bugs.ruby-lang.org/issues/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` configure argument). +* ASAN will only work when using Clang version 18 or later - it requires [this + bugfix](https://github.com/llvm/llvm-project/pull/75290) related to + multithreaded `fork`. +* ASAN has only been tested so far with Clang on Linux. It may or may not work + with other compilers or on other platforms - please file an issue on + [https://bugs.ruby-lang.org](https://bugs.ruby-lang.org) if you run into + problems with such configurations (or, to report that they actually work + properly!) +* In particular, although I have not yet tried it, I have reason to believe + ASAN will _not_ work properly on macOS yet - the fix for the multithreaded + fork issue was actually reverted for macOS (see + [here](https://github.com/llvm/llvm-project/commit/2a03854e4ce9bb1bcd79a211063bc63c4657f92c)). Please + open an issue on [https://bugs.ruby-lang.org](https://bugs.ruby-lang.org) if + this is a problem for you. ## How to measure coverage of C and Ruby code @@ -220,11 +262,12 @@ 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 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. +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: https://rubyci.org/coverage