2015-02-05 83 views
3

我需要編譯靜態鏈接到lua庫(liblua.a)並動態鏈接到dl庫(libdl.so)的模塊。靜態鏈接lua庫後缺少符號

我編譯的C源文件(generic_loader.c)連接起來,延胡索庫:被證明

$ 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 [email protected]@GLIBC_2.2.5 
00000000000008d0 t deregister_tm_clones 
       U [email protected]@GLIBC_2.2.5 
       U [email protected]@GLIBC_2.2.5 
       U [email protected]@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 [email protected]@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?

在此先感謝。

+1

您的'_loader.o'文件不是常規的目標文件,而是「共享對象」(so)文件。從第一個編譯器咒語中刪除'-shared'和'-ldl',並添加'-c'來獲得一個普通的目標文件。 – siffiejoe 2015-02-05 23:08:47

+0

按照您的建議,我發現運行第二個編譯時出錯: 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):在創建共享對象時,不能使用針對'luaO_nilobject_'的重定位R_X86_64_32;使用-fPIC重新編譯 /usr/local/lib/liblua.a:添加符號時出錯:錯誤值 collect2:錯誤:ld返回1退出狀態 – ericariello 2015-02-06 12:12:38

+0

這是因爲靜態庫中的目標文件編譯時沒有使用「-fpic」 (或'-fPIC')標誌。 – siffiejoe 2015-02-09 11:01:51

回答

0

要混合動態鏈接和靜態鏈接,您可能需要使用和-Wl,-Bdynamic選項,如this SO answer中所述。

+0

試過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):在創建共享對象時不能使用針對'luaO_nilobject_'的重定位R_X86_64_32;用-fPIC重新編譯 /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/liblua5.1.a:添加符號時出錯:錯誤值 collect2:錯誤:ld返回1退出狀態 – ericariello 2015-02-06 12:36:34

+0

這意味着您應該將-fPIC添加到您的liblua編譯中。 – llogiq 2015-05-26 12:33:39