【问题标题】:Symbols missing after statically linking lua library静态链接lua库后符号丢失
【发布时间】:2015-04-05 10:43:09
【问题描述】:

我需要编译一个静态链接到 lua 库 (liblua.a) 并动态链接到 dl 库 (libdl.so) 的模块。

我已经编译了 C 源文件 (generic_loader.c),将其链接到 dl 库:

$ gcc -g generic_loader.c -shared -fpic -ldl -o _loader.o

没有显示错误,因为我可以看到链接的库和符号解析:

$ ldd _loader.o
_loader.o:
linux-vdso.so.1 =>  (0x00007fff231fe000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7397949000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7397582000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7397d6e000)

$ nm _loader.o
_loader.o:
0000000000201078 B __bss_start
0000000000201078 b completed.6972
                 w __cxa_finalize@@GLIBC_2.2.5
00000000000008d0 t deregister_tm_clones
                 U dlerror@@GLIBC_2.2.5
                 U dlopen@@GLIBC_2.2.5
                 U dlsym@@GLIBC_2.2.5
0000000000000940 t __do_global_dtors_aux
0000000000200df0 t __do_global_dtors_aux_fini_array_entry
0000000000201070 d __dso_handle
0000000000200e00 d _DYNAMIC
0000000000201078 D _edata
0000000000201080 B _end
0000000000000aec T _fini
0000000000000980 t frame_dummy
0000000000200de8 t __frame_dummy_init_array_entry
0000000000000ba8 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000007e8 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200df8 d __JCR_END__
0000000000200df8 d __JCR_LIST__
                 w _Jv_RegisterClasses
00000000000009b5 T load_as_global
0000000000000aab T luaopen_genericloader
                 U lua_pushboolean
                 U lua_pushcclosure
                 U lua_pushnil
                 U lua_pushstring
                 U lua_setfield
                 U lua_tolstring
0000000000000900 t register_tm_clones
0000000000201078 d __TMC_END__

未解析的符号属于lua库,应该在下一步处理,所以我猜那个二进制文件没有问题。

所以我编译了生成的二进制文件 _loader.so 以便将其静态链接到 lib lua:

$ gcc -g -shared -fpic _loader.o /usr/local/lib/liblua.a -o genericloader.so

同样,没有显示错误。但是当我列出符号时,所有的 dl 和 lua 符号都不见了,还有 load_as_global 和 luaopen_genericloader,这两个函数都在 generic_loader.c 中定义:

$ldd genericloader.so 
genericloader.so:
linux-vdso.so.1 =>  (0x00007fff7cdfe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f360ad0d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f360b2f4000)

$ nm genericloader.so 

genericloader.so:
0000000000201030 B __bss_start
0000000000201030 b completed.6972
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000000530 t deregister_tm_clones
00000000000005a0 t __do_global_dtors_aux
0000000000200e08 t __do_global_dtors_aux_fini_array_entry
0000000000201028 d __dso_handle
0000000000200e18 d _DYNAMIC
0000000000201030 D _edata
0000000000201038 B _end
0000000000000618 T _fini
00000000000005e0 t frame_dummy
0000000000200e00 t __frame_dummy_init_array_entry
0000000000000628 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000004e0 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200e10 d __JCR_END__
0000000000200e10 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000000560 t register_tm_clones
0000000000201030 d __TMC_END__

我是否遗漏了某些内容、编译中的一个步骤或者可能是 gcc 的一个选项?

提前致谢。

【问题讨论】:

  • 您的_loader.o 文件不是常规对象文件,而是“共享对象”(so)文件。从第一个编译器咒语中删除 -shared-ldl 并添加 -c 以获得正常的目标文件。
  • 按照您的建议,我发现运行第二次编译时出错:gcc -g -shared -fpic loader.o /usr/local/lib/liblua.a -o genericloader.so - ldl /usr/bin/ld: /usr/local/lib/liblua.a(lapi.o): relocation R_X86_64_32 against `luaO_nilobject' 在制作共享对象时不能使用;使用 -fPIC /usr/local/lib/liblua.a 重新编译:添加符号时出错:错误值 collect2:错误:ld 返回 1 退出状态
  • 这是因为静态库中的目标文件是在没有-fpic(或-fPIC)标志的情况下编译的。

标签: c lua static-linking dynamic-linking


【解决方案1】:

要混合动态和静态链接,您可能需要使用 this SO answer 中所述的 -Wl,-Bstatic-Wl,-Bdynamic 选项。

【讨论】:

  • 试过 gcc -g -shared -fpic generic_loader.c -Wl,-Bstatic -llua5.1 -Wl,-Bdynamic -ldl -o genericloader.so /usr/bin/ld: /usr/ lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/liblua5.1.a(lapi.o): 重定位 R_X86_64_32 对 `luaO_nilobject_' 制作时不能使用共享对象;使用 -fPIC /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/liblua5.1.a 重新编译:添加符号时出错:错误值 collect2:错误: ld 返回 1 个退出状态
  • 这意味着你应该将 -fPIC 添加到你的 liblua 编译中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 2020-11-10
  • 2014-03-24
相关资源
最近更新 更多