尝试编译使用 libruby.so 的 C 程序时,链接器未找到 ruby 符号(例如 ruby_init)

问题描述 投票:0回答:1

我按照以下说明编译 ruby:https://docs.ruby-lang.org/en/master/contributing/building_ruby_md.html#label-Quick+start+guide

然后我制作了这个使用 ruby 接口的简单 C 程序:

#include "ruby.h"

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

    /* Ruby goes here */

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

我用这个简单的脚本编译程序:

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

然后我收到这些错误:

/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

现在,我已经验证了 ruby_init 实际上位于 libruby.so 文件内。这是 objdump 输出 (

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:


我还制作了一个加载共享库并调用该函数的 C 程序:



#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;
}


我尝试将 ruby 库重新编译为静态库,但也遇到了同样的错误。还尝试运行

make clean
然后运行
make -j8
.

成功调用 ruby_init 函数。为什么仅在尝试链接其他 C 程序时才会出现链接错误?预先感谢!

ruby linker linker-errors ruby-c-extension c-api
1个回答
0
投票

您遇到的错误似乎不是 Ruby 特定的,只是链接 C 库的一般问题。

这可能只是链接器顺序问题。尝试将

./oof.c
放在所有
-l
参数之前。

© www.soinside.com 2019 - 2024. All rights reserved.