On 9/13/06, Lyle Johnson <lyle.johnson / gmail.com> wrote:
> On 9/13/06, John Gabriele <jmg3000 / gmail.com> wrote:
>
> > Thanks for the explanation Lyle. I'm sorry, but perhaps I was unclear
> > (and also still not understanding this). I'm looking to find out the
> > mechanism at work *at link-edit time*, when you're building the
> > extension module. [snip]
>
> Oh, OK. Well, I can't tell you the *specific* arguments because
> they're highly platform-dependent. But the easiest way (IMO) to find
> out what they should be is to write an extconf.rb script (a standard
> fixture for any Ruby extension) and then run that. [snip]

Ok. I think I partly get it now. Details follow for anyone who's interested.

To save some time, I grabbed the sample extension from
http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html
and it builds and runs fine (note, I've got Ruby installed in /opt/ruby-1.8.4) :

==== snip ====
module-experiment/MyTest$ ruby extconf.rb
creating Makefile

module-experiment/MyTest$ ls
extconf.rb  Makefile  MyTest.c

module-experiment/MyTest$ make
gcc -fPIC -g -O2  -I. -I/opt/ruby-1.8.4/lib/ruby/1.8/i686-linux
-I/opt/ruby-1.8.4/lib/ruby/1.8/i686-linux -I.   -c MyTest.c
MyTest.c:23:2: warning: no newline at end of file

gcc -shared  -L'/opt/ruby-1.8.4/lib' -Wl,-R'/opt/ruby-1.8.4/lib' -o
mytest.so MyTest.o  -ldl -lcrypt -lm   -lc

module-experiment/MyTest$ ls -lh mytest.so
-rwxr-xr-x 1 john john 8.2K 2006-09-14 02:48 mytest.so

module-experiment/MyTest$ cd ..

module-experiment$ ls
MyTest  mytest.rb

module-experiment$ ruby mytest.rb
10
==== /snip ====


The compile command is simple, though contains some harmless redundancy.

The fancy options in the linker command (this is Linux-/GCC-/ELF-specific) are:

* The "-shared" tells the link-editor to build a shared object (a .so file).

* The "-L" simply tells gcc where it can find libraries to link to at
link-edit time. As you can see from the size of mytest.so (8.2 kB),
it's certainly not statically linking in my libruby-static.a. Note
that in the MyTest.c file, there's at least one call to a rb_foo
function, so I'd think that gcc at least needs to *look* at
libruby-static.a...

* The "-Wl,-R..." option means to pass the "-R'/opt/ruby-1.8.4/lib'"
option to the link-editor. Looking it up (see "man ld"), I see that it
means for the link-editor to add the /opt/ruby-1.8.4/lib directory to
the runtime search path, and also, as the docs say: "The -rpath option
is also used when locating shared objects which are needed by shared
objects explicitly included in the link; see the description of the
-rpath-link option."

* Then there's that "-ldl"...

Anyhow, this is where things are still fuzzy for me (though it could
be that it's 3:30 in the morning). How gcc builds mytest.so so it can
later hook into ruby is probably accomplished by some combination of
that -R option, that libdl.so shared lib (which seems to supply
dlopen()), and maybe even the /opt/ruby-1.8.4/lib/libruby-static.a
static lib. Not sure. Anyway, there seems to be some semi-deep
GNU/Linux magic happening here.

Thanks!
---John