ruby-ll icon indicating copy to clipboard operation
ruby-ll copied to clipboard

ruby-ll won’t compile with Ruby 3.4

Open GuillaumeLestringant opened this issue 7 months ago • 1 comments

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.

GuillaumeLestringant avatar May 20 '25 16:05 GuillaumeLestringant

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 avatar Jun 02 '25 16:06 cover

@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

GuillaumeLestringant avatar Jun 06 '25 15:06 GuillaumeLestringant

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.

bneumeier avatar Jun 13 '25 23:06 bneumeier

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"

bneumeier avatar Jun 13 '25 23:06 bneumeier

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!

ronaldtse avatar Jun 16 '25 14:06 ronaldtse

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.

yorickpeterse avatar Aug 11 '25 20:08 yorickpeterse

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).

bneumeier avatar Aug 11 '25 21:08 bneumeier

Thanks to @jbigler for fixing this! Version 2.1.4 should now work with GCC 15.

yorickpeterse avatar Sep 05 '25 14:09 yorickpeterse

All my gratitude to @jbigler !

GuillaumeLestringant avatar Sep 06 '25 10:09 GuillaumeLestringant