symengine.rb
symengine.rb copied to clipboard
symengine.rb does not work with static libruby, requires shared object but does not enforce requirement
I just did a fresh install of symengine and symengine.rb on an Ubuntu VM. My Ruby is 2.3.0 in rbenv (user install). There are no errors when I build/install the gem, which is cloned from github (HEAD).
Unfortunately, when I attempt to load symengine in pry, I get the following error:
[1] pry(main)> require "symengine"
LoadError: incompatible library version - /home/dev/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/symengine-0.1.0/lib/symengine/symengine.so
from /home/dev/.rbenv/versions/2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
I tried building the gem manually, using cmake, and checked that the Ruby paths were correct in the cmake config. They are — they point to the rbenv ruby-2.3.0 headers.
UPDATE: I get the same error when attempting to use Ruby 2.2.4.
Thanks @mohawkjohn for trying it! Any ideas what might be causing this?
Only thing I can come up with is that it's not correctly linking libruby.
For example, see this bug: https://github.com/brianmario/mysql2/issues/657
Unfortunately, when I do ldd symengine.so
, it doesn't list libruby at all. I'm not really sure why that would be.
I've also tried removing my system ruby — so only rbenv versions remain — and it doesn't appear to help.
I do notice that symengine.rb's link.txt
includes libruby-static.a.
Okay, that may have put me onto something: https://github.com/rbenv/ruby-build/issues/35
Testing my hypothesis now.
@abinashmeher999, @isuruf, any ideas?
@mohawkjohn, can you reinstall with this line uncommented https://github.com/symengine/symengine.rb/blob/master/cmake/FindRuby.cmake#L54 and then post the build log?
Okay! I found the problem. symengine.rb requires that libruby be a shared object, which rb-env/ruby-build doesn't produce by default.
So two things need to be done:
- symengine.rb needs to enforce that libruby.so is linked instead of libruby-static.a.
- rbenv users need to install using
CONFIGURE_OPTS=--enable-shared rbenv install 2.3.0
, where 2.3.0 is the desired Ruby version.
@mohawkjohn do most Ruby libraries link the static libruby
? If so, why not to change symengine to simply link the static version as well?
Honestly, I'm unsure. My intuition tells me you need the shared object, but I can't say why in this case.
@mohawkjohn Thanks for reporting this! I use rbenv too but as far as I remember I didn't have to do anything like CONFIGURE_OPTS
. I will double check. 2.3.0 too needs to be added to travis.
About the enforcing part, ideally the gem should work with either of the cases. We can enforce it for now till we come up with a solution that works with either kind of libruby.
Oops my mistake. I had been using rvm not rbenv. I got a little confused.
I tried with rbenv
and it fails at link time (not load time like @mohawkjohn) because ruby was not built with PIC.
Linking C shared library ../../lib/symengine/symengine.so
/usr/bin/ld: /home/isuru/.rbenv/versions/2.3.0/lib/libruby-static.a(array.o): relocation R_X86_64_PC32 against symbol `rb_eIndexError' can not be used when making a shared object; recompile with -fPIC
I tried setting CFLAGS, but it doesn't seem to pick it up.
CONFIGURE_OPTS
on the other hand builds a shared library which also adds -fPIC
and works fine for me.