链接时,不同静态库中的同一对象文件
Same object file in different static libraries when linking
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 中的重复符号会发生什么情况?是否有任何标志要求不生成符号重复错误?
当同一个对象文件出现在提供的多个库中时,链接多个静态库不会导致任何重复符号错误(默认情况下(。
这是因为链接器不会将静态库"合并"到最终的可执行文件中。它仅将提供的目标文件合并到可执行文件中。链接器从左到右处理对象文件和存档库的列表。遇到静态库时,链接器会检查是否有任何库提供的对象文件定义了当前未定义的符号。然后,也只有这样,才会拉入该对象文件。
在您的示例中:
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
中存在的符号:
- 链接器将处理并添加
obj1.o
到lib.so
,注意所述符号是未定义的。 - 链接器将打开
dir1/lib1.a
并检查存档中包含的任何对象文件是否定义了所述符号。由于foo.o
定义了符号,因此foo.o
将被添加到lib.so
并且符号将被标记为已定义。 - 链接器将打开
dir2/lib2.a
。但是当前没有未定义的符号,因此将忽略重复的对象文件。 - 链接器将处理
obj2.o
并将其添加到lib.so
。链接器不会返回并重新处理lib1.a
或lib2.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 是不同的,并且总是将所有遇到的对象文件(来自静态库(添加到输出中。
相关文章:
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何在h文件中包含.o对象文件
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 从对象文件(.o)在macos上制作归档文件(.a文件)
- 检测 COFF 对象文件中C++内联符号
- 特定对象文件的单线程生成
- 使用对象文件读取三角形数据网格
- 链接时,不同静态库中的同一对象文件
- 防止临时对象文件访问 MSVC 中的磁盘
- 对在不同二进制文件中创建的对象文件的依赖关系
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 是否有正确的方法对生成文件中的对象文件使用模板命令?(C++)
- ./main:加载共享库时出错:libopencv_highgui.so.4.0:无法打开共享对象文件:没有这样的文件或
- 使用 make 将对象文件放在特定目录中
- 如何从 3d 对象文件中获取 3d 坐标
- 为什么我的生成文件没有生成对象文件?
- 如何在OSX上正确创建C++对象文件(.o)
- sf::Windows上的音乐:api-ms-win-crt-locale-l1-1-0.dll:无法打开共享对象文件
- 使用nvcc(CUDA-RINSIDE)正确链接对象文件
- 链接节点本机模块中的提升库,对象文件需要替代库版本