我试图通过将所有的对象文件合并到一个.o
文件中,来减少包含大量(~3000)小对象文件(.o
)的大型静态库libIn.a
的磁盘大小;据我所知,这个过程被称为“部分链接”。2通过将所有的对象部分(每个.o
文件一个)折叠成一个单独的部分来实现大小的减小。
我看到的问题是,我使用的过程没有保留.o
文件(包括libIn.a
)中包含的符号的全局性,即,所有符号在部分链接后都变为局部,这会在链接过程的下游导致“未定义符号”错误。
例如,这就是version.o
对象文件(最初包含在libIn.a
中,您可以在https://github.com/giovanniberi93/problematic_object_file下载version.o
)在执行部分链接之前的样子:
└─ nm -Ca version.o
0000000000000000 T webrtc::LoadWebRTCVersionInRegister()
0000000000000024 s l_.str
0000000000000000 t ltmp0
0000000000000024 s ltmp1
所以现在符号webrtc::LoadWebRTCVersionInRegister()
是全局的(T
)。
但是当执行部分链接时,相同的符号变为本地(t
):
└─ ld -r version.o -o why_is_local.o
└─ nm -Ca why_is_local.o
0000000000000024 s LC1
0000000000000000 t webrtc::LoadWebRTCVersionInRegister()
事情变得更奇怪了:当尝试使用.o
示例文件复制相同的场景时,全局符号不会转换为局部符号(!);例如,使用输入C++文件:
int function1() {
return 1;
}
其全局符号function1()
不通过执行部分链接而被转换成局部符号,即,其在部分链接之前和之后保持全局(T
):
└─ clang -c file1.cc
└─ nm -Ca file1.o
0000000000000000 T function1()
0000000000000000 t ltmp0
0000000000000008 s ltmp1
└─ ld -r file1.o -o relocated.o
└─ nm -Ca relocated.o
0000000000000000 T function1()
version.o
和file1.o
中一定有一些差异导致全局符号变为局部符号,但我无法精确定位。任何输入都将非常感谢。
我的环境(MacOS 12.6,arm 64):
└─ clang -v
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: arm64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Users/giober/Desktop/XCodes/13.1/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
└─ ld -v
@(#)PROGRAM:ld PROJECT:ld64-711
BUILD 18:11:19 Aug 3 2021
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 13.0.0, (clang-1300.0.29.3) (static support for 27, runtime is 27)
TAPI support using: Apple TAPI version 13.0.0 (tapi-1300.0.6.5)
└─ nm --version
Apple LLVM version 13.0.0 (clang-1300.0.29.3)
Optimized build.
Default target: arm64-apple-darwin21.6.0
Host CPU: vortex
1条答案
按热度按时间wn9m85ua1#
所述符号标记为“私有外部”:
不知道这是从哪里来的,但是可以使用
-keep_private_externs
来保持这种状态: