我正在尝试通过将所有对象文件组合成一个
libIn.a
文件来减少包含大量(~3000)小对象文件(.o
)的大型静态库 .o
的磁盘大小;据我了解,这个过程称为“部分链接”。可以通过将所有对象部分(每个 .o
文件一个)折叠为一个来实现尺寸减小。
我看到的问题是,我正在使用的过程不保留
.o
文件中包含的符号的全局性,即,所有符号在部分链接后都变成本地的,这会导致链接过程下游出现“未定义符号”错误。举个例子,这就是 libIn.a
目标文件(最初包含在
version.o
中,您可以在 https://github.com/giovanniberi93/problematic_object_file下载
libIn.a
)在 before 执行部分链接时的样子:
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()
文件复制相同的场景时,
全局符号不会转换为本地符号 (!);例如,使用输入 C++ 文件:
.o
其全局符号
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
一定存在一些差异,导致全局符号变成本地符号,但我无法确定它。任何意见将不胜感激。
我的环境(MacOS 12.6,arm64):file1.o
└─ 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
不确定它来自哪里,但您可以使用
% nm -m version.o
0000000000000000 (__TEXT,__text) private external __ZN6webrtc27LoadWebRTCVersionInRegisterEv
0000000000000024 (__TEXT,__cstring) non-external l_.str
0000000000000000 (__TEXT,__text) non-external ltmp0
0000000000000024 (__TEXT,__cstring) non-external ltmp1
来保留此状态:
-keep_private_externs