Linker not finding ruby symbols (such as ruby_init) when trying to compile C program which uses libruby.so

0

I followed these instructions to compile ruby: https://docs.ruby-lang.org/en/master/contributing/building_ruby_md.html#label-Quick+start+guide

Then I made this simple C program which uses the ruby interface:

#include "ruby.h"

int main(int argc, char* argv[])
{
    /* construct the VM */
    ruby_init();

    /* Ruby goes here */

    /* destruct the VM */
    return ruby_cleanup(0);
}

I compile the program with this simple script:

gcc -c -I/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/include/ruby-3.3.0+0/x86_64-linux -I/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/include/ruby-3.3.0+0 -L/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/lib -Wl,--compress-debug-sections=zlib -Wl,-rpath,/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/lib -lruby -lm -lpthread -Iinstall/include/ruby-3.3.0+0 -Iinstall/include/ruby-3.3.0+0/x86_64-linux -Linstall/lib/ -L.  ./oof.c -o oof.o



gcc -I/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/include/ruby-3.3.0+0/x86_64-linux -I/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/include/ruby-3.3.0+0 -L/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/lib -Wl,--compress-debug-sections=zlib -Wl,-rpath,/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/lib -lruby -lm -lpthread -Iinstall/include/ruby-3.3.0+0 -Iinstall/include/ruby-3.3.0+0/x86_64-linux -Linstall/lib/ -L. ./oof.o -o oof

then I get these errors:

/usr/bin/ld: ./oof.o: in function `main':
oof.c:(.text+0x23): undefined reference to `ruby_init'
/usr/bin/ld: oof.c:(.text+0x2d): undefined reference to `ruby_cleanup'
collect2: error: ld returned 1 exit status

Now, I have verified that ruby_init is actually inside the libruby.so file. Here is the objdump output (objdump --disassemble=ruby_init libruby.so):


libruby.so:     file format elf64-x86-64


Disassembly of section .init:

Disassembly of section .plt:

Disassembly of section .plt.got:

Disassembly of section .text:

00000000000fa290 <ruby_init>:
   fa290:   f3 0f 1e fa             endbr64 
   fa294:   48 83 ec 08             sub    $0x8,%rsp
   fa298:   e8 63 c9 f4 ff          call   46c00 <ruby_setup@plt>
   fa29d:   85 c0                   test   %eax,%eax
   fa29f:   75 05                   jne    fa2a6 <ruby_init+0x16>
   fa2a1:   48 83 c4 08             add    $0x8,%rsp
   fa2a5:   c3                      ret    
   fa2a6:   e8 15 b3 f4 ff          call   455c0 <rb_ruby_debug_ptr@plt>
   fa2ab:   48 f7 00 fb ff ff ff    testq  $0xfffffffffffffffb,(%rax)
   fa2b2:   75 0a                   jne    fa2be <ruby_init+0x2e>
   fa2b4:   bf 01 00 00 00          mov    $0x1,%edi
   fa2b9:   e8 82 9a f4 ff          call   43d40 <exit@plt>
   fa2be:   66 48 8d 3d 32 a5 42    data16 lea 0x42a532(%rip),%rdi        # 5247f8 <ruby_current_ec@@Base+0x5247c8>
   fa2c5:   00 
   fa2c6:   66 66 48 e8 d2 b2 f4    data16 data16 rex.W call 455a0 <__tls_get_addr@plt>
   fa2cd:   ff 
   fa2ce:   b9 24 00 00 00          mov    $0x24,%ecx
   fa2d3:   ba 04 00 00 00          mov    $0x4,%edx
   fa2d8:   48 8b 38                mov    (%rax),%rdi
   fa2db:   48 8b 77 78             mov    0x78(%rdi),%rsi
   fa2df:   e8 9c fc ff ff          call   f9f80 <rb_ec_error_print_detailed>
   fa2e4:   eb ce                   jmp    fa2b4 <ruby_init+0x24>

Disassembly of section .fini:


I also made a C program which loads the shared library and calls that function:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>

int main(int argc, char** argv)
{
    void *handle;
    void (*init_func)();


    handle = dlopen("./libruby.so", RTLD_LAZY);
    if (!handle) {
        /* fail to load the library */
        fprintf(stderr, "Error: %sn", dlerror());
        return EXIT_FAILURE;
    }

    *(void**)(&init_func) = dlsym(handle, "ruby_init");
    if (!init_func) {
        /* no such symbol */
        fprintf(stderr, "Error: %sn", dlerror());
        dlclose(handle);
        return EXIT_FAILURE;
    }

    init_func();
    dlclose(handle);

    return EXIT_SUCCESS;
}


I have tried to recompile the ruby library as a static library, but I got the same errors too. Also tried to run make clean and then make -j8 .

which succesfully calls the ruby_init function. Why does the link errors only occur when trying to link the other C program? Thanks in advance!

Edit: Solved! Thanks to Max for suggesting that the linking order matters. After running gcc ./oof.o -I/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/include/ruby-3.3.0+0/x86_64-linux -I/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/include/ruby-3.3.0+0 -L/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/lib -Wl,--compress-debug-sections=zlib -Wl,-rpath,/home/cyberhacker/Asioita/Hakkerointi/Rubydatetime/ruby/install/lib -lruby -lm -lpthread -Iinstall/include/ruby-3.3.0+0 -Iinstall/include/ruby-3.3.0+0/x86_64-linux -Linstall/lib/ -L. -o oof it links correctly.