Symbol lookup error

49 views
Skip to first unread message

Abinash Meher

unread,
Jun 14, 2015, 6:37:09 PM6/14/15
to sciru...@googlegroups.com, Ondřej Čertík
Hi everyone,

I am stuck at an error with the ruby_wrappers for SymEngine. I have a module SymEngine, under which I have a class Basic. As described here. ext/symengine/symengine.c

With the current extconf.rb. I get an error like this
abinashmeher999@JARVIS:~/gsoc/symengine/src/ruby$ irb
2.2.0 :001 > require 'symengine'
 => true
2.2.0 :002 > a = SymEngine::Basic.new
irb: symbol lookup error: /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so: undefined symbol: basic_init

Then I found this question, Ruby C Extensions, loading external libraries. I followed that, but the have_library function always returned false because there's no main in libsymengine.a. Therefore, I set the function to look for to basic_init. Still no progress. I have commented the part where I tried that in extconf.rb. Can anyone please help in what am I doing wrong?

If I skip that part and directly use append_library, I get an error like this
abinashmeher999@JARVIS:~/gsoc/symengine/src/ruby$ irb
2.2.0 :001 > require 'symengine'
LoadError: /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so: undefined symbol: __cxa_pure_virtual - /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine.rb:1:in `<top (required)>'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in `require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in `rescue in require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:39:in `require'
    from (irb):1
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main>'

Any idea what might be wrong?

Regards,
Abinash Meher

Ondřej Čertík

unread,
Jun 14, 2015, 7:08:19 PM6/14/15
to Abinash Meher, sciru...@googlegroups.com
Hi Abinash,

On Sun, Jun 14, 2015 at 4:36 PM, Abinash Meher
<abinashda...@gmail.com> wrote:
> Hi everyone,
>
> I am stuck at an error with the ruby_wrappers for SymEngine. I have a module
> SymEngine, under which I have a class Basic. As described here.
> ext/symengine/symengine.c

For others, I think Abinash is referring to his PR:
https://github.com/sympy/symengine/pull/414, probably the latest
commit as of this writing: 345dbfc3243d78a4e8f7bad9565b2092590aa022

>
> With the current extconf.rb. I get an error like this
>>
>> abinashmeher999@JARVIS:~/gsoc/symengine/src/ruby$ irb
>> 2.2.0 :001 > require 'symengine'
>> => true
>> 2.2.0 :002 > a = SymEngine::Basic.new
>> irb: symbol lookup error:
>> /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so:
>> undefined symbol: basic_init

basic_init is defined here:

https://github.com/sympy/symengine/blob/6a518b8fcaba48229b933d86cb962f6f366894f6/src/cwrapper.cpp#L32

and it is linked into the libsymengine.so (or .a) library. The library
symengine.so seems to be the Ruby wrappers, is that right? If so,
either it doesn't link against libsymengine.so, or it can't find the
library at runtime. Can you do:

ldd /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so

to see if it is linked. Did you compile symengine as static or dynamic
library? If static (the default), then ldd will not show anything. One
would need to examine how the symengine.so was linked --- if you can
post the gcc command that linked it, all would become clear.

>
>
> Then I found this question, Ruby C Extensions, loading external libraries. I
> followed that, but the have_library function always returned false because
> there's no main in libsymengine.a. Therefore, I set the function to look for
> to basic_init. Still no progress. I have commented the part where I tried
> that in extconf.rb. Can anyone please help in what am I doing wrong?
>
> If I skip that part and directly use append_library, I get an error like
> this
>>
>> abinashmeher999@JARVIS:~/gsoc/symengine/src/ruby$ irb
>> 2.2.0 :001 > require 'symengine'
>> LoadError:
>> /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so:
>> undefined symbol: __cxa_pure_virtual -

This symbol is defined in the C++ standard library. You have to
compile the C wrappers using a C++ compiler to link against it.

>> /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so
>> from
>> /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in
>> `require'
>> from
>> /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in
>> `require'
>> from
>> /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine.rb:1:in
>> `<top (required)>'
>> from
>> /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in
>> `require'
>> from
>> /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in
>> `rescue in require'
>> from
>> /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:39:in
>> `require'
>> from (irb):1
>> from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/bin/irb:11:in
>> `<main>'
>
>
> Any idea what might be wrong?

Ondrej

Isuru Fernando

unread,
Jun 14, 2015, 11:30:54 PM6/14/15
to abinashda...@gmail.com, Ondřej Čertík, sciru...@googlegroups.com
Hi

On Mon, Jun 15, 2015 at 4:06 AM, Abinash Meher <abinashda...@gmail.com> wrote:
Hi everyone,

I am stuck at an error with the ruby_wrappers for SymEngine. I have a module SymEngine, under which I have a class Basic. As described here. ext/symengine/symengine.c

With the current extconf.rb. I get an error like this
abinashmeher999@JARVIS:~/gsoc/symengine/src/ruby$ irb
2.2.0 :001 > require 'symengine'
 => true
2.2.0 :002 > a = SymEngine::Basic.new
irb: symbol lookup error: /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so: undefined symbol: basic_init

Then I found this question, Ruby C Extensions, loading external libraries. I followed that, but the have_library function always returned false because there's no main in libsymengine.a. Therefore, I set the function to look for to basic_init. Still no progress. I have commented the part where I tried that in extconf.rb. Can anyone please help in what am I doing wrong?

First include the header you need using have_header. (eg. have_header(cwrapper.h))

Take a look at mkmf.log after including a have_library('symengine', 'basic_init') statement.
You'll realise that the example program is like this

/* begin */
 1: #include "ruby.h"
 2: 
 3: /*top*/
 4: extern int t(void);
 5: int main(int argc, char **argv)
 6: {
 7:   if (argc > 1000000) {
 8:     printf("%p", &t);
 9:   }
10: 
11:   return 0;
12: }
13: int t(void) { void ((*volatile p)()); p = (void ((*)()))basic_init; return 0; }
/* end */

which is not what you want. Instead have a simple program to compile and include the headers. You can do that by passing arguments to have_library

have_library('symengine', 'basic p; basic_init(p); basic_free(p)', 'cwrapper.h')

You'll also want to do a append_library call


If I skip that part and directly use append_library, I get an error like this
abinashmeher999@JARVIS:~/gsoc/symengine/src/ruby$ irb
2.2.0 :001 > require 'symengine'
LoadError: /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so: undefined symbol: __cxa_pure_virtual - /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine.rb:1:in `<top (required)>'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in `require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:128:in `rescue in require'
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:39:in `require'
    from (irb):1
    from /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main>'

Any idea what might be wrong?

Regards,
Abinash Meher

--
You received this message because you are subscribed to the Google Groups "SciRuby Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sciruby-dev...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Abinash Meher

unread,
Jun 15, 2015, 3:32:26 AM6/15/15
to Ondřej Čertík, sciru...@googlegroups.com
Hi Ondrej,


Can you do:

ldd /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so

to see if it is linked. Did you compile symengine as static or dynamic
library? If static (the default), then ldd will not show anything. One
would need to examine how the symengine.so was linked --- if you can
post the gcc command that linked it, all would become clear.

Yes. symengine.so are the wrappers. This is the output

ldd /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so
    linux-vdso.so.1 =>  (0x00007ffe44cee000)
    libruby.so.2.2 => /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/libruby.so.2.2 (0x00007f31288af000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3128577000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f31281b2000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3127f9b000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3127d7d000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3127b79000)
    libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f312793f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3129115000)

And I compiled it as static library, which was the default. Is there a preference of one over the other? I tried what Isuru suggested, and this(mkmf.log) is the output. It also contains the gcc commands. It did achieve in a way what Isuru suggested. But there are many more errors.


This symbol is defined in the C++ standard library. You have to
compile the C wrappers using a C++ compiler to link against it.

I see. Isn't that what the extconf.rb is already doing. If not, how do I set a specific compiler to be used. Meanwhile, I will look for it on the internet.

Regards,
Abinash Meher

Abinash Meher

unread,
Jun 15, 2015, 3:42:07 AM6/15/15
to Isuru Fernando, Ondřej Čertík, sciru...@googlegroups.com
Hi Isuru,

Thanks again! I tried it out and the example program now makes more sense(see mkmf.log). I will have to read more about how the have_library works. Because as I can see it's not always the function name only. Most of the other usages of same have_library on github have mentioned only the entry functions like *_init as the second parameter.

You'll also want to do a append_library call

I am not sure about this one. I read the source
# File lib/mkmf.rb, line 837
def have_library(lib, func = nil, headers = nil, &b)
  func = "main" if !func or func.empty?
  lib = with_config(lib+'lib', lib)
  checking_for checking_message("#{func}()", LIBARG%lib) do
    if COMMON_LIBS.include?(lib)
      true
    else
      libs = append_library($libs, lib)
      if try_func(func, libs, headers, &b)
        $libs = libs
        true
      else
        false
      end
    end
  end
end
The have_library call does that for us. I might have to try one with and one without append_library to be sure.

Regards,
Abinash Meher

Isuru Fernando

unread,
Jun 15, 2015, 3:56:24 AM6/15/15
to sciru...@googlegroups.com, Ondřej Čertík
Hi,

On Mon, Jun 15, 2015 at 1:01 PM, Abinash Meher <abinashda...@gmail.com> wrote:
Hi Ondrej,

Can you do:

ldd /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so

to see if it is linked. Did you compile symengine as static or dynamic
library? If static (the default), then ldd will not show anything. One
would need to examine how the symengine.so was linked --- if you can
post the gcc command that linked it, all would become clear.

Yes. symengine.so are the wrappers. This is the output

ldd /home/abinashmeher999/.rvm/gems/ruby-2.2.0/gems/symengine-0.0.0.pre/lib/symengine/symengine.so
    linux-vdso.so.1 =>  (0x00007ffe44cee000)
    libruby.so.2.2 => /home/abinashmeher999/.rvm/rubies/ruby-2.2.0/lib/libruby.so.2.2 (0x00007f31288af000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3128577000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f31281b2000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3127f9b000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3127d7d000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3127b79000)
    libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f312793f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3129115000)

And I compiled it as static library, which was the default. Is there a preference of one over the other? I tried what Isuru suggested, and this(mkmf.log) is the output. It also contains the gcc commands. It did achieve in a way what Isuru suggested. But there are many more errors.

You should build symengine (C++ library) as a shared library.
cmake -DBUILD_SHARED_LIBS=on .

Otherwise if you build a static library you will need to link each of the dependencies of symengine (teuchos, gmp, etc.)

Ondřej Čertík

unread,
Jun 15, 2015, 9:11:48 AM6/15/15
to Abinash Meher, sciru...@googlegroups.com

The errors in the gist you posted are caused by compiling with gcc instead of g++.

Sent from my mobile phone.

Abinash Meher

unread,
Jun 15, 2015, 10:44:42 AM6/15/15
to Ondřej Čertík, sciru...@googlegroups.com
So I built using shared libs and tried adding these to extconf.rb following from nmatrix and other similar extconf.rb code on github
CONFIG['CC'] = 'g++'
CONFIG['CXX'] = 'g++'
$CPPFLAGS='-Wall -O3 -Wall -Wcast-qual -Wconversion -DSGI__gnu_cxx -DREADLINE'

This is the new error message and mkmf.log. We can clearly see g++ being used, but only for few commands


Regards,
Abinash Meher

Ondřej Čertík

unread,
Jun 15, 2015, 11:46:50 AM6/15/15
to Abinash Meher, sciru...@googlegroups.com
On Mon, Jun 15, 2015 at 8:44 AM, Abinash Meher
<abinashda...@gmail.com> wrote:
> So I built using shared libs and tried adding these to extconf.rb following
> from nmatrix and other similar extconf.rb code on github
> CONFIG['CC'] = 'g++'
> CONFIG['CXX'] = 'g++'
> $CPPFLAGS='-Wall -O3 -Wall -Wcast-qual -Wconversion -DSGI__gnu_cxx
> -DREADLINE'
>
> This is the new error message and mkmf.log. We can clearly see g++ being
> used, but only for few commands

These errors look like are caused by the lines:

-unless have_header('cwrapper.h')
- raise 'cwrapper.h not found'
-end
-unless have_library('symengine',
- 'basic p; basic_init(p); basic_free(p)',
- 'cwrapper.h')
- abort 'Unable to find basic_init in library symengine!'
-end

It looks like these lines do not honor the include paths for the rest
of the wrappers, so they fail to find gmp and so on.
Just remove them for now. Then it should start working, at least for me.

Ondrej

Abinash Meher

unread,
Jun 15, 2015, 11:51:23 AM6/15/15
to Ondřej Čertík, sciru...@googlegroups.com
Does this work only with dynamic version of the libsymengine library? Because I keep getting the same error. I have libsymengine.a.

Regards,
Abinash Meher

Ondřej Čertík

unread,
Jun 15, 2015, 11:59:59 AM6/15/15
to Abinash Meher, sciru...@googlegroups.com
On Mon, Jun 15, 2015 at 9:50 AM, Abinash Meher
<abinashda...@gmail.com> wrote:
> Does this work only with dynamic version of the libsymengine library?
> Because I keep getting the same error. I have libsymengine.a.

Yes, as Isuru said, you need to use the dynamic version, otherwise you
need to set paths to gmp and other libs.

Ondrej
Reply all
Reply to author
Forward
0 new messages