Hi,
Help!
SUMMARY: A C program calling Ruby (embedded) loads extension
libraries automatically (ie ld.so finds them and links).
But when I have a Perl script calling the same C program (via
a Swig-generated C wrapper), I get run-time link errors! Why?
DESCRIPTION:
I’ve wrapped some database access routines in Ruby, and want
to call them from Perl (don’t ask!).
I’m using:
Perl: 5.6.1
Ruby: 1.6.7
swig: 1.3
A Ruby stub calling the Ruby database routines works OK and
accesses the database (Mysql).
And a C stub calling the Ruby database routines (embedded
Ruby) also works OK.
Bue when I use SWIG to wrap the C layer to call it from Perl,
calling Ruby code works, EXCEPT when calling Ruby extensions.
The extensions .so files get opened (strace tells me), but
Ruby symbols don’t get resolved.
To debug and illustrate what happens, I wrapped a 'runruby’
function that executes a Ruby string:
THIS WORKS:
test.pl
A Perl script calling embedded Ruby
···
use regdb;
$res = regdb::runruby(“puts Time.new”);
exit 0;
$ perl test.pl
Sat Aug 10 14:55:04 BST 2002
$
BUT THIS DOESN’T:
test.pl
A Perl script calling embedded Ruby
use regdb;
$res = regdb::runruby(“
require 'digest/md5’
puts Digest::MD5.new(‘hello’)
”);
$ 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
(eval): uninitialized constant Digest (NameError)
(eval): [BUG] Segmentation fault
ruby 1.6.7 (2002-03-01) [i686-linux]
Aborted
As you can see, the library (.so) gets found,
but rb_cObject remains undefined.
BUT IT DOES IF I LINK EVERY EXTENSION LIBRARY ‘DIRECTLY’:
ie instead of (makefile excerpt):
ldflags = -lruby -lm -ldl -lcrypt -export-dynamic
ld -G test.o test_wrap.o -o test.so -L$(rubylib) $(ldflags)
I use:
ldflags = -lruby -lm -ldl -lcrypt -export-dynamic
ld -G test.o test_wrap.o
/opt/lib/ruby/1.6/i686-linux/digest/md5.so
/opt/lib/ruby/1.6/i686-linux/digest.so
-o test.so -L$(rubylib) $(ldflags)
$ perl test.pl
5d41402abc4b2a76b9719d911017c592
$
ie, I explicitly specify every Ruby extension .so I want to
link with, at link time. But of course, this happens when
calling from Perl, and not when I run the Ruby functions from
the command line, or call them from the C program.
The problem is that the more Ruby extensions I use, the more
I have to explicitly specify them at link time. Worse, I want
to use database drivers, via Ruby’s DBI, but I won’t know
until runtime which drivers I want to use.
Is there a way I can have all extension libraries loaded
correctly by Ruby at run-time?
I’m sure I don’t understand some of the intricacies of the
linking process with Swig.
Can you help?!
Many thanks in advance,
Peter Munro