【发布时间】: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