【发布时间】:2018-08-14 00:16:05
【问题描述】:
我正在开发一个链接 Clang 的工具,我需要对某些操作进行少量更改。为了缩短开发时间,而不是重建 Clang,我决定重新定义我的程序代码中感兴趣的符号,并让链接器处理其余部分:in most cases,在两个程序代码中定义的符号的程序版本并且静态库在链接时优先考虑,而不会大惊小怪。 (链接的答案与 Linux 有关,但我发现它通常也可以在 macOS 上工作。)
当我使用可从 LLVM 网站下载的 macOS 库存 Clang 构建时,这非常有用。但是,我目前正在尝试切换到我公司的自定义 Clang(我从源代码构建过一次,并希望以相同的方式进一步修改),现在我得到重复符号错误。
我不知道是什么导致了这个问题。我的项目的链接器标志保持不变(除了一个新的静态库):重要的是,它们不包含-all_load 或其表亲-force_load,它们告诉链接器尝试包含静态库中定义的每个符号。当我在股票档案和自定义档案中使用nm 检查它们时,我试图覆盖的符号的定义方式相同。不同之处在于我构建 LLVM 的方式,但仅仅知道这一点并不能真正帮助我弄清楚我需要改变什么。
例如,假设我想重新定义clang::Qualifiers::getAsString() const。使用股票 LLVM 库我可以做到这一点,但现在我会得到一个重复的符号错误:
duplicate symbol __ZNK5clang10Qualifiers11getAsStringEv in:
.../Objects-normal/x86_64/TypePrinter.o
clang+llvm-internal/lib/libclangAST.a(TypePrinter.cpp.o)
使用nm -f darwin 来检查两个档案,对于__ZNK5clang10Qualifiers11getAsStringEv,我会得到非常相似的结果:
# clang+llvm-6.0.0/lib/libclangAST.a
(undefined) external __ZNK5clang10Qualifiers11getAsStringEv
0000000000000bb0 (__TEXT,__text) external __ZNK5clang10Qualifiers11getAsStringEv
# clang+llvm-internal/lib/libclangAST.a
(undefined) external __ZNK5clang10Qualifiers11getAsStringEv
0000000000000d00 (__TEXT,__text) external __ZNK5clang10Qualifiers11getAsStringEv
那么,假设或多或少相同的符号定义和相同的链接器标志,为什么我以前能够以这种方式覆盖静态库符号,为什么我不再能够?
【问题讨论】: