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