truffleruby
truffleruby copied to clipboard
Support the Rice C++ extenstion
There are plenty Ruby native gems written in C++ using rice gem. Currently, there is no option to compile them with TruffleRuby. Especially, there are missing C++ tools bundled with TruffleRuby.
Will TruffleRuby support them? What complications are connected with this support?
Could you give some example gems, preferably the ones you would be interested in or are widely used? What's the error you get when trying to install one of them?
We already support unf_ext, which is a C++ extension.
E.g. rice what is a glue for other C++ gem extensions.
$ gem install rice
Building native extensions. This could take a while...
ERROR: Error installing rice:
ERROR: Failed to build gem native extension.
current directory: ~/.gem/truffleruby/2.6.6/gems/rice-2.2.0
~/.rubies/truffleruby-dev/bin/truffleruby -I ~/.rubies/truffleruby-dev/lib/mri -r ./siteconf20200813-42356-1ebmxtv.rb extconf.rb
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --output=aclocal.m4t
Can't exec "aclocal": No such file or directory at /usr/local/Cellar/autoconf/2.69/share/autoconf/Autom4te/FileUtils.pm line 326.
autoreconf: failed to run aclocal: No such file or directory
<internal:core> core/errno.rb:48:in `handle': No such file or directory - configure (Errno::ENOENT)
from <internal:core> core/io.rb:1003:in `sysopen'
from <internal:core> core/file.rb:1281:in `initialize'
from <internal:core> core/io.rb:724:in `new'
from <internal:core> core/io.rb:724:in `open'
from post-autoconf.rb:6:in `process'
from post-autoconf.rb:16:in `<main>'
Post-processing configure
sh: configure: No such file or directory
Makefile not found
Gem files will remain installed in ~/.gem/truffleruby/2.6.6/gems/rice-2.2.0 for inspection.
Results logged to ~/.gem/truffleruby/2.6.6/extensions/x86_64-darwin/20.3.0-dev-f610a725/rice-2.2.0/gem_make.out
Yes, the issue above I can resolve by brew install automake. But I'd expect this bundled in TruffleRuby since it's bringing own tool chain to compile gems. After that I get this anyway
$ gem install rice
ERROR: Error installing rice:
ERROR: Failed to build gem native extension.
current directory: ~/.gem/truffleruby/2.6.6/gems/rice-2.2.0
~/.rubies/truffleruby-dev/bin/truffleruby -I ~/.rubies/truffleruby-dev/lib/mri -r ./siteconf20200813-49879-yayjju.rb extconf.rb
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/local/Cellar/autoconf/2.69/bin/autoconf
autoreconf: running: /usr/local/Cellar/autoconf/2.69/bin/autoheader
autoreconf: running: automake --add-missing --copy --no-force
sample/Makefile.am:26: warning: addsuffix /Makefile,$(RICE_SAMPLES: non-POSIX variable name
sample/Makefile.am:26: (probably a GNU make extension)
parallel-tests: installing './test-driver'
autoreconf: Leaving directory `.'
Post-processing configure
Post-processing ./Makefile.in
Post-processing ./rice/Makefile.in
Post-processing ./ruby/Makefile.in
Post-processing ./ruby/lib/Makefile.in
Post-processing ./sample/Makefile.in
Post-processing ./test/Makefile.in
Post-processing ./test/ext/Makefile.in
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for g++... g++
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of g++... none
checking for ranlib... ranlib
checking build system type... x86_64-apple-darwin18.7.0
checking host system type... x86_64-apple-darwin18.7.0
checking whether g++ supports C++11 features by default... no
configure: No compiler with C++11 support was found
checking for ruby.h... no
configure: error: could not find ruby.h (check config.log)
Makefile not found
Gem files will remain installed in ~/.gem/truffleruby/2.6.6/gems/rice-2.2.0 for inspection.
Results logged to ~/.gem/truffleruby/2.6.6/extensions/x86_64-darwin/20.3.0-dev-f610a725/rice-2.2.0/gem_make.out
Yes, the issue above I can resolve by
brew install automake. But I'd expect this bundled in TruffleRuby since it's bringing own tool chain to compile gems. After that I get this anyway
TruffleRuby and GraalVM come with its own LLVM toolchain. autotools/automake is independent of that, it's a layer above the C/C++ compiler/linker/etc.
It looks like the extconf.rb of rice is not detecting the right compiler, we'll investigate.
The rice gem seems to be at https://github.com/jasonroelofs/rice/tree/2.2.0
Since it uses autoconf, the compiler needs to be in PATH, or the CC/CXX/etc variables be set. With this it goes further:
$ PATH=$(ruby -e 'print Truffle::Boot.toolchain_paths(:PATH)'):$PATH LD_LIBRARY_PATH=$(ruby -e 'print Truffle::Boot.toolchain_paths(:LD_LIBRARY_PATH)') gem i rice
Building native extensions. This could take a while...
ERROR: Error installing rice:
ERROR: Failed to build gem native extension.
...
In file included from ./detail/Auto_Function_Wrapper.hpp:895:
./detail/Auto_Function_Wrapper.ipp:66:7: error: called object type 'VALUE' (aka 'unsigned long') is not a function or function pointer
rb_scan_args(argc, argv, args->formatString(Num_Args - 1).c_str()
^
/home/eregon/.rubies/truffleruby-dev/lib/cext/include/truffleruby/truffleruby.h:82:265: note: expanded from macro 'rb_scan_args'
#define rb_scan_args(ARGC, ARGV, FORMAT, ...) SCAN_ARGS_IMPL(__VA_ARGS__, rb_tr_scan_args_10, rb_tr_scan_args_9, rb_tr_scan_args_8, rb_tr_scan_args_7, rb_tr_scan_args_6, rb_tr_scan_args_5, rb_tr_scan_args_4, rb_tr_scan_args_3, rb_tr_scan_args_2, rb_tr_scan_args_1)(ARGC, ARGV, FORMAT, __VA_ARGS__)
~~~~~~~~~~~ ^
...
In file included from Class.cpp:1:
In file included from ./Class.hpp:5:
In file included from ./Class.ipp:4:
In file included from ./Module.ipp:4:
In file included from ./Module_impl.ipp:1:
In file included from ./detail/define_method_and_auto_wrap.hpp:29:
In file included from ./detail/define_method_and_auto_wrap.ipp:4:
In file included from ./detail/wrap_function.hpp:338:
In file included from ./detail/wrap_function.ipp:11:
In file included from ./detail/Auto_Member_Function_Wrapper.hpp:894:
./detail/Auto_Member_Function_Wrapper.ipp:2683:5: error: expected expression
rb_scan_args(argc, argv, "0");
^
/home/eregon/.rubies/truffleruby-dev/lib/cext/include/truffleruby/truffleruby.h:82:247: note: expanded from macro 'rb_scan_args'
#define rb_scan_args(ARGC, ARGV, FORMAT, ...) SCAN_ARGS_IMPL(__VA_ARGS__, rb_tr_scan_args_10, rb_tr_scan_args_9, rb_tr_scan_args_8, rb_tr_scan_args_7, rb_tr_scan_args_6, rb_tr_scan_args_5, rb_tr_scan_args_4, rb_tr_scan_args_3, rb_tr_scan_args_2, rb_tr_scan_args_1)(ARGC, ARGV, FORMAT, __VA_ARGS__)
^
...
The first error looks like we need more variants for rb_tr_scan_args_*:
https://github.com/jasonroelofs/rice/blob/b42193a7c6154343869ec12d10d6caf1ab1cc349/rice/detail/Auto_Function_Wrapper.ipp#L66-L67
And the second is a rather strange call to rb_scan_args with no arguments?
Maybe just to check no arguments are passed?
https://github.com/jasonroelofs/rice/blob/b42193a7c6154343869ec12d10d6caf1ab1cc349/rice/detail/Auto_Member_Function_Wrapper.ipp#L2683
And our macro doesn't support no arguments yet.
IIRC, rice also #undef rb_define_method as it wants a variadic version. But that should be fine since rb_define_method is a function on TruffleRuby (also on MRI < 2.7).
I renamed this issue, because we support several C++ extensions already. Rice not yet.