ruby-ll won’t compile with Ruby 3.4
Since switching to Ruby 3.4, the native extension part of ruby-ll won’t compile anymore.
Here’s the result of gem install ruby-ll --verbose
HEAD https://index.rubygems.org/versions
200 OK
GET https://index.rubygems.org/info/ruby-ll
200 OK
GET https://index.rubygems.org/info/ansi
200 OK
GET https://index.rubygems.org/info/ast
200 OK
Downloading gem ruby-ll-2.1.3.gem
GET https://index.rubygems.org/gems/ruby-ll-2.1.3.gem
Fetching ruby-ll-2.1.3.gem
200 OK
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/.yardopts
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/LICENSE
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/README.md
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/bin/ruby-ll
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/doc/css/common.css
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/doc/driver_architecture.md
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/driver.c
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/driver.h
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/driver_config.c
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/driver_config.h
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/extconf.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/khash.h
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/kvec.h
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/libll.c
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/libll.h
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c/macros.h
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/java/Libll.java
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/java/org/libll/Driver.java
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/java/org/libll/DriverConfig.java
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/ast/node.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/branch.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/cli.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/code_generator.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/compiled_configuration.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/compiled_grammar.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/configuration_compiler.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/driver.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/driver_config.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/driver_template.erb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/epsilon.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/erb_context.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/grammar_compiler.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/lexer.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/message.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/operator.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/parser.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/parser_error.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/rule.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/setup.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/source_line.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/terminal.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/token.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/lib/ll/version.rb
/home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ruby-ll.gemspec
Building native extensions. This could take a while...
current directory: /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c
["/usr/bin/ruby", "extconf.rb"]
creating Makefile
current directory: /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c
["make", "DESTDIR=", "sitearchdir=./.gem.20250520-25244-oxwwcg", "sitelibdir=./.gem.20250520-25244-oxwwcg", "clean"]
current directory: /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c
["make", "DESTDIR=", "sitearchdir=./.gem.20250520-25244-oxwwcg", "sitelibdir=./.gem.20250520-25244-oxwwcg"]
compiling driver.c
driver.c: Dans la fonction « ll_driver_allocate »:
driver.c:54:5: attention: « rb_data_object_get_warning » est obsolète: by TypedData [-Wdeprecated-declarations]
54 | Data_Get_Struct(config, DriverConfig, state->config);
| ^~~~~~~~~~~~~~~
Dans le fichier inclus depuis /usr/include/ruby-3.4.0/ruby/internal/core.h:27,
depuis /usr/include/ruby-3.4.0/ruby/ruby.h:29,
depuis /usr/include/ruby-3.4.0/ruby.h:38,
depuis driver.h:4,
depuis driver.c:1:
/usr/include/ruby-3.4.0/ruby/internal/core/rdata.h:325:1: note: déclaré ici
325 | rb_data_object_get_warning(VALUE obj)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
driver.c:59:5: attention: « rb_data_object_wrap_warning » est obsolète: by TypedData [-Wdeprecated-declarations]
59 | return Data_Wrap_Struct(klass, ll_driver_mark, ll_driver_free, state);
| ^~~~~~
/usr/include/ruby-3.4.0/ruby/internal/core/rdata.h:293:1: note: déclaré ici
293 | rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
driver.c: Dans la fonction « ll_driver_each_token »:
driver.c:92:5: attention: « rb_data_object_get_warning » est obsolète: by TypedData [-Wdeprecated-declarations]
92 | Data_Get_Struct(self, DriverState, state);
| ^~~~~~~~~~~~~~~
/usr/include/ruby-3.4.0/ruby/internal/core/rdata.h:325:1: note: déclaré ici
325 | rb_data_object_get_warning(VALUE obj)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
driver.c: Dans la fonction « ll_driver_parse »:
driver.c:312:5: attention: « rb_data_object_get_warning » est obsolète: by TypedData [-Wdeprecated-declarations]
312 | Data_Get_Struct(self, DriverState, state);
| ^~~~~~~~~~~~~~~
/usr/include/ruby-3.4.0/ruby/internal/core/rdata.h:325:1: note: déclaré ici
325 | rb_data_object_get_warning(VALUE obj)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
Dans le fichier inclus depuis /usr/include/ruby-3.4.0/ruby/internal/assume.h:29,
depuis /usr/include/ruby-3.4.0/ruby/backward/2/assume.h:24,
depuis /usr/include/ruby-3.4.0/ruby/defines.h:72,
depuis /usr/include/ruby-3.4.0/ruby/ruby.h:25:
/usr/include/ruby-3.4.0/ruby/internal/anyargs.h:363:45: erreur: passage de l'argument 5 de « rb_block_call » depuis un type pointeur incompatible [-Wincompatible-pointer-types]
363 | # define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
/usr/include/ruby-3.4.0/ruby/internal/cast.h:31:29: note: dans la définition de la macro « RBIMPL_CAST »
31 | # define RBIMPL_CAST(expr) (expr)
| ^~~~
driver.c:329:9: note: dans l'expansion de la macro « RUBY_METHOD_FUNC »
329 | RUBY_METHOD_FUNC(ll_driver_each_token),
| ^~~~~~~~~~~~~~~~
Dans le fichier inclus depuis /usr/include/ruby-3.4.0/ruby/ruby.h:41:
/usr/include/ruby-3.4.0/ruby/internal/iterator.h:324:90: note: « rb_block_call_func_t » {alias « long unsigned int (*)(long unsigned int, long unsigned int, int, const long unsigned int *, long unsigned int) »} attendu mais l'argument est de type « VALUE (*)(void) » {alias « long unsigned int (*)(void) »}
324 | VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2);
| ~~~~~~~~~~~~~~~~~~~~~^~~~
/usr/include/ruby-3.4.0/ruby/internal/iterator.h:88:29: note: « rb_block_call_func_t » déclaré ici
88 | typedef rb_block_call_func *rb_block_call_func_t;
| ^~~~~~~~~~~~~~~~~~~~
make: *** [Makefile:251: driver.o] Error 1
ERROR: Error installing ruby-ll:
ERROR: Failed to build gem native extension.
current directory: /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c
/usr/bin/ruby extconf.rb
current directory: /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c
make DESTDIR\= sitearchdir\=./.gem.20250520-25244-oxwwcg sitelibdir\=./.gem.20250520-25244-oxwwcg clean
current directory: /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3/ext/c
make DESTDIR\= sitearchdir\=./.gem.20250520-25244-oxwwcg sitelibdir\=./.gem.20250520-25244-oxwwcg
Building has failed. See above output for more information on the failure.
make failed, exit code 2
Gem files will remain installed in /home/myname/.local/share/gem/ruby/3.4.0/gems/ruby-ll-2.1.3 for inspection.
Results logged to /home/myname/.local/share/gem/ruby/3.4.0/extensions/x86_64-linux/3.4.0/ruby-ll-2.1.3/gem_make.out
Sorry it’s in French. Most of it is just warnings, but this in the error.
/usr/include/ruby-3.4.0/ruby/internal/anyargs.h:363:45: erreur: passage de l'argument 5 de « rb_block_call » depuis un type pointeur incompatible [-Wincompatible-pointer-types]
363 | # define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))
Meaning argument 5 of rb_block_call gets passed using an incompatible pointer type.
Here’s for gem env
RubyGems Environment:
- RUBYGEMS VERSION: 3.6.9
- RUBY VERSION: 3.4.3 (2025-04-14 patchlevel 32) [x86_64-linux]
- INSTALLATION DIRECTORY: /usr/lib/ruby/gems/3.4.0
- USER INSTALLATION DIRECTORY: /home/myname/.local/share/gem/ruby/3.4.0
- CREDENTIALS FILE: /home/myname/.local/share/gem/credentials
- RUBY EXECUTABLE: /usr/bin/ruby
- GIT EXECUTABLE: /usr/bin/git
- EXECUTABLE DIRECTORY: /usr/bin
- SPEC CACHE DIRECTORY: /home/myname/.cache/gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /usr/lib/ruby/gems/3.4.0
- /home/myname/.local/share/gem/ruby/3.4.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => true
- :bulk_threshold => 1000
- "gem" => "--user-install"
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /bin/internet
- /bin/media
- /bin/mensaria
- /home/myname/.local/bin
- /usr/local/bin
- /usr/bin
- /bin
- /usr/local/sbin
- /usr/lib/jvm/default/bin
- /usr/bin/site_perl
- /usr/bin/vendor_perl
- /usr/bin/core_perl
Obviously, I’m using the latest version of RubyGems.
I'm having a similar issue, and it looks like brotli also had it and it was caused by some changes in gcc 15.
As a quick attempt, I've tried to fork and remove the RUBY_METHOD_FUNC and try with that but it didn't work.
For now my workaround to install it locally was to install gcc 14 and set that in the [in my case] ~/.local/share/mise/installs/ruby/3.1.2/lib/ruby/3.1.0/x86_64-linux/rbconfig.rb as CONFIG["CC"] = "gcc-14", and then it was able to install it.
@cover I just tried your workaround and it worked perfectly. In my case, I had to change the parameter in /usr/lib/ruby/3.4.0/x86_64-linux/rbconfig.rb but from there, it was smooth sailing. As a consequence, I changed the title of this issue to reflect the fact that the version of Ruby isn’t the problem.
PING @kraft001
Hi, I just ran into the same issue, and was able to get the gem to install by specifying additional CFLAGS. Specifically:
$ gem install ruby-ll -v 2.1.3 -- --with-cflags="-std=gnu17"
Building native extensions with: '--with-cflags=-std=gnu17'
This could take a while...
Successfully installed ruby-ll-2.1.3
Parsing documentation for ruby-ll-2.1.3
Installing ri documentation for ruby-ll-2.1.3
Done installing documentation for ruby-ll after 0 seconds
1 gem installed
This is a common fix when dealing with GCC 15 breakage -- in GCC 15, the language standard used by default is C23, I think. So, programs and libraries that choke in that version will often work if you simply select the previous default.
Further experimentation shows that you can alternatively specify --with-cflags="-Wno-incompatible-pointer-types" and that also works around the issue.
I should have also said, if you're using bundler you can set the override with the incantation:
bundle config build.ruby-ll --with-cflags="-std=gnu17"
Thank you @bneumeier for the workaround!
For those who rely on ruby-ll on Windows Ruby 3.4 using GitHub Actions, the workaround can be applied via the .bundle/config file, as we (with @kraft001) have done here:
- https://github.com/lutaml/moxml/pull/32
Hope this helps others too!
It seems the real/proper fix here is to stop using RUBY_METHOD_FUNC and replace it with whatever the latest version of Ruby requires.
While I don't work on ruby-ll/oga myself these days, I'll happily accept a PR making such a change and release it.
For anyone who is interested in working on this further -- I think this may be the same thing discussed at https://bugs.ruby-lang.org/issues/21293, for which there's a comment:
This is because in C23 void foo(); no longers means "foo takes an unspecified number of arguments", and there is no way to implement a working ANYARGS AFAIK.
Not something people would run into in practice, I hope.
and:
rb_define_method is a rusty API. Its design dates back to when matz still used K&R C. C evolved since then. We have coped with the language updates but are having hard times recently. Maybe either we want a "modern" C API, or we want to stop following the C standard (which many projects do anyway).
Thanks to @jbigler for fixing this! Version 2.1.4 should now work with GCC 15.
All my gratitude to @jbigler !