Skip to content

ruby-dev and Ruby < 3.2 compiled with -O0 on Fedora 42+ #2637

Closed

Description

@eregon

Steps to reproduce the behavior

$ ruby-build -d ruby-dev ~/.rubies 
$ chruby ruby-dev
$ ruby -e 'p RbConfig::CONFIG["CFLAGS"]'
"-std=gnu17  -fPIC"
$ ruby -rbenchmark -e 'p Benchmark.realtime { 30_000_000.times {} }'
7.393558286999905

Compare that to Ruby built from source:

$ chruby ruby-master
$ ruby -e 'p RbConfig::CONFIG["CFLAGS"]'
"-fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2  -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef"
$ ruby -rbenchmark -e 'p Benchmark.realtime { 30_000_000.times {} }'
0.9954729659984878

CFLAGS shows no -O flag, so it's the default, -O0 and very slow (~7x).

Caused by #2543.

Also affects Ruby < 3.2 as well:

$ ruby-build ruby-3.1.6 -d ~/.rubies
$ chruby 3.1.6                                                      
$ ruby -e 'p RbConfig::CONFIG["CFLAGS"]'                            
"-std=gnu17  -fPIC"
$ ruby -rbenchmark -e 'p Benchmark.realtime { 30_000_000.times {} }'
3.8961724789987784

Expected vs. actual behavior

Logs

Activity

  1. eregon commented on Aug 31, 2026

    @eregon
    MemberAuthor

    Using cflags instead of CFLAGS is the obvious fix, that appends instead of overrides, giving:

    $ ruby -e 'p RbConfig::CONFIG["CFLAGS"]'                            
    "-fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -std=gnu17  -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef  -fPIC"
    $ ruby -rbenchmark -e 'p Benchmark.realtime { 30_000_000.times {} }'
    0.8652950529976806
    
    diff --git i/bin/ruby-build w/bin/ruby-build
    index 52fc7e0b..c5fb8b36 100755
    --- i/bin/ruby-build
    +++ w/bin/ruby-build
    @@ -748,7 +748,15 @@ build_package_standard() {
           #
           # TODO: Consider changing this to check for GCC v15 specifically
           # rather than inspecting the OS itself.
    -      export CFLAGS="-std=gnu17 $CFLAGS"
    +      if [ "${CFLAGS+defined}" ]; then
    +        export CFLAGS="-std=gnu17 $CFLAGS"
    +      else
    +        # Use the `cflags` configure variable, which Ruby's configure appends to
    +        # its default optflags/debugflags/warnflags, unlike CFLAGS which would
    +        # override them and notably lose the -O3, producing a much slower Ruby.
    +        # configure ignores `cflags` when CFLAGS is given, hence the branch above.
    +        export cflags="-std=gnu17 $cflags"
    +      fi
         fi
         # ./configure --prefix=/path/to/ruby
         # shellcheck disable=SC2086,SC2153
    

    There is also another bug here, that ruby-dev is considered < 3.2.

  2. eregon commented on Aug 31, 2026

    @eregon
    MemberAuthor

    BTW RUBY_CFLAGS also overrides CFLAGS, which means getting -O0 unless one has a -O flag in RUBY_CFLAGS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions