
Update: Re: Perl calling C calling Ruby (linking problem)
Hi,
Just wanted to update you on a problem I've been having, so that this
appears in the archives and it may help someone else.
I'm calling Ruby embedded from a Perl script using swig. I'd been
getting errors like this when calling out to Ruby extensions (like
digest/MD5):
Quote:
> The error is:
> $ perl test.pl
> Ruby exception: /opt/lib/ruby/1.6/i686-linux/digest/md5.so: undefined symbol: rb_cObject -> /opt/lib/ruby/1.6/i686-linux/digest/md5.so
> $
The problem was in the way I'd built Ruby. I'd done the normal:
./configure && make && make install
But this builds static libraries (libruby.a). I'd found out I needed to
build a dynamic one (libruby.so), so I'd gone back to my build
directory and done:
./configure --enable-shared && make && make install
This then created libruby.so. BUT this didn't re-build all the
extension libraries. In particular:
$ ldd /opt/lib/ruby/1.6/i686-linux/digest/md5.so
libc.so.6 => /lib/libc.so.6 (0x4000e000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
$
As you can see, there's no mention of libruby.so. And comparing an
strace across two machines showed me that my script was opening md5.so,
but _not_ digest.so. I then removed my Ruby build directory, the Ruby
libraries (md5.so etc), re-extracted Ruby from the tarball, and
re-built everything as above with the --enable-shared option. This gave
me:
$ ldd /opt/lib/ruby/1.6/i686-linux/digest/md5.so
libruby.so.1.6 => /opt/lib/libruby.so.1.6 (0x40003000)
libc.so.6 => /lib/libc.so.6 (0x400a1000)
libdl.so.2 => /lib/libdl.so.2 (0x40145000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x4014a000)
libm.so.6 => /lib/libm.so.6 (0x40177000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
$
That did the trick.
Many thanks to Nobu Nakada and Guy Decoux for their help.
Best regards,
Peter Munro
--- Guy Decoux wrote ---
Quote:
>>>>>> "P" == Peter Munro writes:
> P> I'm running:
> P> Ruby 1.67
> P> Perl 5.6.1
> P> swig 1.3
> Well there is a problem
> pigeon% ls
> a.pl* regdb.i ruby.i
> pigeon%
> pigeon% cat regdb.i
> %module regdb
> %{
> #include "ruby.h"
> %}
> %include ruby.i
> pigeon%
> pigeon% cat ruby.i
> %{
> static int initi = 0;
> %}
> %inline %{
> int init(void) {
> if (!initi) {
> ruby_init();
> ruby_init_loadpath();
> initi = 1;
> }
> return 0;
> }
> char *runruby(char *c) {
> VALUE res;
> int error = 0;
> if (!initi) {
> init();
> }
> res = rb_eval_string_protect(c, &error);
> if (error) {
> res = rb_gv_get("$!");
> }
> res = rb_obj_as_string(res);
> return RSTRING(res)->ptr;
> }
> %}
> pigeon%
> swig was compiled with :
> ./configure --prefix=/home/ts/local/sw --enable-perl5 --with-ruby=/home/ts/local/r167/bin/ruby
> pigeon% ~/local/sw/bin/swig -version
> SWIG Version 1.3.14u-20020813-1606
> Copyright (c) 1995-1998
> University of Utah and the Regents of the University of California
> Copyright (c) 1998-2001
> University of Chicago
> Compiled with CC
> pigeon%
> pigeon% perl -v
> This is perl, v5.6.1 built for i386-linux
> Copyright 1987-2001, Larry Wall
> Perl may be copied only under the terms of either the Artistic License or the
> GNU General Public License, which may be found in the Perl 5 source kit.
> Complete documentation for Perl, including FAQ lists, should be found on
> this system using `man perl' or `perldoc perl'. If you have access to the
> Internet, point your browser at http://www.*-*-*.com/ , the Perl Home Page.
> pigeon%
> pigeon% ~/local/r167/bin/ruby -v
> ruby 1.6.7 (2002-03-01) [i686-linux]
> pigeon%
> pigeon% ~/local/sw/bin/swig -perl regdb.i
> pigeon%
> pigeon% gcc -c regdb_wrap.c -I/usr/lib/perl/5.6.1/CORE -Dbool=char -I/home/ts/local/r167/lib/ruby/1.6/i686-linux
> In file included from /home/ts/local/r167/lib/ruby/1.6/i686-linux/ruby.h:610,
> from regdb_wrap.c:515:
> /home/ts/local/r167/lib/ruby/1.6/i686-linux/intern.h:258: warning: `yyparse' redefined
> /usr/lib/perl/5.6.1/CORE/embed.h:756: warning: this is the location of the previous definition
> /home/ts/local/r167/lib/ruby/1.6/i686-linux/intern.h:259: warning: `yylex' redefined
> /usr/lib/perl/5.6.1/CORE/embed.h:755: warning: this is the location of the previous definition
> /home/ts/local/r167/lib/ruby/1.6/i686-linux/intern.h:260: warning: `yyerror' redefined
> /usr/lib/perl/5.6.1/CORE/embed.h:751: warning: this is the location of the previous definition
> pigeon%
> pigeon% ld -shared regdb_wrap.o -L/home/ts/local/r167/lib -lruby -ldl -lm -lcrypt -o regdb.so
> pigeon%
> pigeon% cat a.pl
> #!/usr/bin/perl -l
> use regdb;
> $res = regdb::runruby("
> require 'digest/md5'
> Digest::MD5.new('hello')
> ");
> print $res;
> pigeon%
> pigeon% a.pl
> 5d41402abc4b2a76b9719d911017c592
> pigeon%
> Guy Decoux