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

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 —

···

I’m running:
Ruby 1.67
Perl 5.6.1
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 © 1995-1998
University of Utah and the Regents of the University of California
Copyright © 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' orperldoc perl’. If you have access to the
Internet, point your browser at http://www.perl.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