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: %s\n", dlerror());
return EXIT_FAILURE;
}
*(void**)(&init_func) = dlsym(handle, "ruby_init");
if (!init_func) {
/* no such symbol */
fprintf(stderr, "Error: %s\n", 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.
The error you're getting doesn't seem Ruby-specific, just an issue with linking a C library in general.
It could just be a linker order issue. Try putting ./oof.c
before all of the -l
args.