如何在共享库中保留静态库中的自由函数
How to keep a free function from a static library in a shared library
当我从静态库构建共享库时,它的自由函数消失了。我知道将符号保留在最终库中的解决方法,但我想首先了解为什么我需要此解决方法。
让我们考虑这个源文件:
extern "C" void HERE_I_AM() {}
如果我执行以下命令
g++ test.cpp -shared -o libtest-without-static.so
nm libtest-without-static.so
我可以看到该函数在共享库中可用:
…
0000000000201000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000000590 r __GNU_EH_FRAME_HDR
0000000000000580 T HERE_I_AM <-- HERE
0000000000000468 T _init
w _ITM_deregist
…
但是如果我先在静态库中编译文件
g++ -c test.cpp
ar crf libtest.a test.o
g++ -shared libtest.a -o libtest-with-static.so
nm libtest-with-static.so
则该函数不在共享库中:
0000000000201020 B __bss_start
0000000000201020 b completed.7641
w __cxa_finalize
0000000000000440 t deregister_tm_clones
00000000000004d0 t __do_global_dtors_aux
0000000000200e88 t __do_global_dtors_aux_fini_array_entry
0000000000201018 d __dso_handle
0000000000200e90 d _DYNAMIC
0000000000201020 D _edata
0000000000201028 B _end
000000000000051c T _fini
0000000000000510 t frame_dummy
0000000000200e80 t __frame_dummy_init_array_entry
0000000000000528 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000000408 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000480 t register_tm_clones
0000000000201020 d __TMC_END__
我知道我可以通过使用 -Wl,--whole-archive
或使用静态库符号的 class 成员函数来获取共享库中的函数,但我不知道为什么上面的命令没有产生相同的共享库。
当linker遇到目标文件时,foo.o
在输入序列中它
link无条件地将其放入输出文件(程序或共享库)。
当它遇到静态库时,libbar.a
,它会(默认)检查存档
查找任何目标文件,例如libbar.a(foo.o)
提供未解决的定义
已被目标文件(或共享库)引用的符号
linked.
如果它找到任何这样的目标文件,它会从存档中提取它们并 links 它们
进入输出文件,就像它们在命令行中单独列出一样
并且根本没有提到静态库。如果没有找到,存档
对link年龄没有任何贡献。
在你的第一次编译中-link年龄:
$ g++ test.cpp -shared -o libtest-without-static.so
g++
将其分解(必须)为一个编译步骤和一个 link 步骤,有效地:
$ g++ -c -o temporary.o test.cpp
$ g++ temporary.o -shared -o libtest-without-static.so
其中 temporary.o
是 link 无条件编辑的。
第二个link年龄:
$ g++ -shared libtest.a -o libtest-with-static.so
单独存档成员libtest.a(test.o)
未能定义任何未解决的问题
已经 linked 的引用,因为没有。 libtest.a
对共享库和输出共享库的 linkage 没有任何贡献
不包含符号,但包含 g++ -shared ...
linkage.
的默认库提供的样板
linkage 静态库的默认用途,与单独命名的目标文件不同,是
为 linker 提供一袋目标文件,select 只需要这些文件
满足手头未解决的参考资料。您不需要确切地知道它们将是哪些。你刚才
需要知道它们在那个袋子里。之前你必须 link 至少一个目标文件
任何静态库,如果有任何未解析的引用,静态库
会员可能会满意。或者指定 --whole-archive
.
当我从静态库构建共享库时,它的自由函数消失了。我知道将符号保留在最终库中的解决方法,但我想首先了解为什么我需要此解决方法。
让我们考虑这个源文件:
extern "C" void HERE_I_AM() {}
如果我执行以下命令
g++ test.cpp -shared -o libtest-without-static.so
nm libtest-without-static.so
我可以看到该函数在共享库中可用:
…
0000000000201000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000000590 r __GNU_EH_FRAME_HDR
0000000000000580 T HERE_I_AM <-- HERE
0000000000000468 T _init
w _ITM_deregist
…
但是如果我先在静态库中编译文件
g++ -c test.cpp
ar crf libtest.a test.o
g++ -shared libtest.a -o libtest-with-static.so
nm libtest-with-static.so
则该函数不在共享库中:
0000000000201020 B __bss_start
0000000000201020 b completed.7641
w __cxa_finalize
0000000000000440 t deregister_tm_clones
00000000000004d0 t __do_global_dtors_aux
0000000000200e88 t __do_global_dtors_aux_fini_array_entry
0000000000201018 d __dso_handle
0000000000200e90 d _DYNAMIC
0000000000201020 D _edata
0000000000201028 B _end
000000000000051c T _fini
0000000000000510 t frame_dummy
0000000000200e80 t __frame_dummy_init_array_entry
0000000000000528 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000000408 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000480 t register_tm_clones
0000000000201020 d __TMC_END__
我知道我可以通过使用 -Wl,--whole-archive
或使用静态库符号的 class 成员函数来获取共享库中的函数,但我不知道为什么上面的命令没有产生相同的共享库。
当linker遇到目标文件时,foo.o
在输入序列中它
link无条件地将其放入输出文件(程序或共享库)。
当它遇到静态库时,libbar.a
,它会(默认)检查存档
查找任何目标文件,例如libbar.a(foo.o)
提供未解决的定义
已被目标文件(或共享库)引用的符号
linked.
如果它找到任何这样的目标文件,它会从存档中提取它们并 links 它们 进入输出文件,就像它们在命令行中单独列出一样 并且根本没有提到静态库。如果没有找到,存档 对link年龄没有任何贡献。
在你的第一次编译中-link年龄:
$ g++ test.cpp -shared -o libtest-without-static.so
g++
将其分解(必须)为一个编译步骤和一个 link 步骤,有效地:
$ g++ -c -o temporary.o test.cpp
$ g++ temporary.o -shared -o libtest-without-static.so
其中 temporary.o
是 link 无条件编辑的。
第二个link年龄:
$ g++ -shared libtest.a -o libtest-with-static.so
单独存档成员libtest.a(test.o)
未能定义任何未解决的问题
已经 linked 的引用,因为没有。 libtest.a
对共享库和输出共享库的 linkage 没有任何贡献
不包含符号,但包含 g++ -shared ...
linkage.
linkage 静态库的默认用途,与单独命名的目标文件不同,是
为 linker 提供一袋目标文件,select 只需要这些文件
满足手头未解决的参考资料。您不需要确切地知道它们将是哪些。你刚才
需要知道它们在那个袋子里。之前你必须 link 至少一个目标文件
任何静态库,如果有任何未解析的引用,静态库
会员可能会满意。或者指定 --whole-archive
.