为什么部分链接会使所有符号成为非全局符号?

问题描述 投票:0回答:2

我正在尝试通过将所有对象文件组合成一个

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


c++ linker clang ld mach-o
2个回答
0
投票

└─ 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



0
投票

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