链接时在不同静态库中的同一目标文件

问题描述 投票:1回答:1
clang++ ... foo.cpp ... -o dir1/foo.o
clang++ ... foo.cpp ... -o dir2/foo.o
//The only difference beween the above two clang++ command lines
//is the output directory
llvm-ar ... dir1/lib1.a ...  dir1/foo.o ...
llvm-ar ... dir2/lib2.a ...  dir2/foo.o ...
clang++ ... dir1/lib1.a dir2/lib2.a ... -o lib.so

生成lib.so时,foo.cpp中重复的符号会发生什么?是否要求任何标志不产生符号重复错误?

c++ clang static-linking
1个回答
0
投票

链接多个静态库,当同一目标文件出现在多个提供的库中时,将不是导致任何重复的符号错误(默认情况下。)>

这是因为链接器不会将静态库“合并为最终可执行文件。它仅将提供的目标文件

合并到可执行文件中。链接器从左到右处理目标文件和归档库的列表。遇到静态库时,链接器检查以查看库提供的任何目标文件是否定义了当前未定义的符号。然后,直到那时,才会拉入该目标文件。

在您的示例中:

clang++ ... dir1/lib1.a dir2/lib2.a ... -o lib.so

考虑两个附加的目标文件:

clang++ obj1.o dir1/lib1.a dir2/lib2.a obj2.o -o lib.so

如果obj1.o引用了foo.cpp中存在的符号:

  1. 链接器将处理obj1.o并将其添加到lib.so,请注意该符号未定义。
  2. 链接器将打开dir1/lib1.a,并检查档案中包含的任何目标文件是否定义了该符号。因为foo.o定义了符号,所以foo.o将添加到lib.so并将符号标记为已定义。
  3. 链接器将打开dir2/lib2.a。但是当前没有未定义的符号,因此重复的目标文件将被忽略。
  4. 链接器将处理并将obj2.o添加到lib.so。链接器不会not
  5. 返回并重新处理lib1.alib2.a

    因此,不会出现重复的符号错误(默认情况下,在Linux上)。要更改此行为,可以使用链接器选项--whole-archive

clang++ ... -Wl,--whole-archive dir1/lib1.a dir2/lib2.a -Wl,--no-whole-archive ... -o lib.so

使用--whole-archive,来自指定归档库的所有目标文件将被添加到输出中。上面的命令然后导致foo.cpp中任何符号的“多重定义”错误。

此答案描述了Linux上的行为,我相信AIX是不同的,并且将始终将所有遇到的目标文件(来自静态库)添加到输出中。

© www.soinside.com 2019 - 2024. All rights reserved.