C 链接共享库后,符号丢失
考虑下面列出的两个文件: 文件C 链接共享库后,符号丢失,c,gcc,shared-libraries,C,Gcc,Shared Libraries,考虑下面列出的两个文件: 文件a.c extern int foovar; int foobarize() { return foovar * foovar; } 和文件b.c int foovar = 10; 我编译静态库liba.a和共享库libb.so如下: # liba.a gcc -fPIC -c a.c -o a.o ar cr liba.a a.o ranlib liba.a # libb.so gcc -fPIC -c b.c -o b.o gcc -fPIC -s
a.c
extern int foovar;
int foobarize() {
return foovar * foovar;
}
和文件b.c
int foovar = 10;
我编译静态库liba.a
和共享库libb.so
如下:
# liba.a
gcc -fPIC -c a.c -o a.o
ar cr liba.a a.o
ranlib liba.a
# libb.so
gcc -fPIC -c b.c -o b.o
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o liba.a
请注意,a.c
中定义的函数foobarize
存在于liba.a
中,但它不存在于libb.so
中。我可以通过发布nm
程序保证:
$ nm liba.a
a.o:
0000000000000000 T foobarize
U foovar
U _GLOBAL_OFFSET_TABLE_
$ nm libb.so
000000000020088c B __bss_start
000000000020088c b completed.6617
w __cxa_finalize@@GLIBC_2.2.5
0000000000000530 t deregister_tm_clones
00000000000005c0 t __do_global_dtors_aux
0000000000200650 t __do_global_dtors_aux_fini_array_entry
0000000000200880 d __dso_handle
0000000000200660 d _DYNAMIC
000000000020088c D _edata
0000000000200890 B _end
0000000000000630 T _fini
0000000000200888 D foovar
0000000000000600 t frame_dummy
0000000000200648 t __frame_dummy_init_array_entry
0000000000000640 r __FRAME_END__
0000000000200858 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
00000000000004d8 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000200658 d __JCR_END__
0000000000200658 d __JCR_LIST__
w _Jv_RegisterClasses
0000000000000570 t register_tm_clones
0000000000200890 d __TMC_END__
如何在libb.so
共享库中获取foobarize
函数?您需要什么:
# force all symbols
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
-Wl,--whole-archive liba.a -Wl,--no-whole-archive
#force just a specific symbol
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
-u foobarize liba.a
您需要它的原因:
静态库是对象文件的简单集合。与一堆对象文件的一个主要区别是:当需要解析未定义的符号时,将搜索库,并且仅链接实际定义符号的对象文件。没有未定义的符号?没有搜索,没有链接。为了覆盖此默认行为,GNU链接器实现了--整个归档文件。大多数链接器实现-u
以强制将特定符号视为未定义。您需要的:
# force all symbols
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
-Wl,--whole-archive liba.a -Wl,--no-whole-archive
#force just a specific symbol
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
-u foobarize liba.a
您需要它的原因:
静态库是对象文件的简单集合。与一堆对象文件的一个主要区别是:当需要解析未定义的符号时,将搜索库,并且仅链接实际定义符号的对象文件。没有未定义的符号?没有搜索,没有链接。为了覆盖此默认行为,GNU链接器实现了--整个归档文件。大多数链接器实现-u
,以强制将特定符号视为未定义。另请参阅,另请参阅和