gpt4 book ai didi

c++ - 如何在共享库中保留静态库中的自由函数

转载 作者:行者123 更新时间:2023-11-30 04:59:15 26 4
gpt4 key购买 nike

当我从静态库构建共享库时,它的自由函数消失了。我知道将符号保留在最终库中的解决方法,但我想首先了解为什么我需要此解决方法。

让我们考虑这个源文件:

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 或让类成员函数使用静态库的符号来获取共享库中的函数,但是我不明白为什么上述命令不会生成相同的共享库。

最佳答案

当链接器遇到目标文件时,输入序列中的foo.o无条件地将其链接到输出文件(程序或共享库)。

当遇到静态库 libbar.a 时,它会(默认)检查存档查找任何目标文件,例如libbar.a(foo.o) 为 Unresolved 问题提供定义已被目标文件(或共享库)引用的符号链接。

如果它找到任何这样的目标文件,它会从存档中提取它们并链接它们进入输出文件,就像它们在命令行中单独列出一样并且根本没有提到静态库。如果没有找到,存档对链接没有任何贡献。

在您的第一个编译和链接中:

$ g++ test.cpp -shared -o libtest-without-static.so

g++ 有效地将其分解(必须)为编译步骤和链接步骤:

    $  g++ -c -o temporary.o test.cpp
$ g++ temporary.o -shared -o libtest-without-static.so

其中 temporary.o 被无条件链接。

在您的第二个链接中:

$ g++ -shared libtest.a -o libtest-with-static.so

单独的存档成员 libtest.a(test.o) 未能定义任何 Unresolved 问题已经链接的引用,因为没有。 libtest.a对共享库和输出共享库的链接没有任何贡献不包含任何符号,但包含 g++ -shared ... 链接的默认库提供的样板。

链接中静态库的默认目的,与单独命名的目标文件不同,是为链接器提供一包目标文件,从中选择它需要的文件满足手头 Unresolved reference 资料。您不需要确切地知道它们将是哪些。你刚才需要知道它们在那个袋子里。您必须先链接至少一个目标文件任何静态库,如果有任何未解析的引用,静态库成员(member)可能会满意。或者指定 --whole-archive

关于c++ - 如何在共享库中保留静态库中的自由函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51330442/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com