【发布时间】:2015-12-20 03:57:13
【问题描述】:
替代标题:为什么我的 dylib 在 Xcode vs Makefile 编译时包含额外的导出符号?
我的公司使用 clang 在 Mac 上构建了一个 c++ 动态库 (dylib),我们最近将我们手工制作的 Makefile 移植到了 CMake 构建系统,现在正在使用生成的 Xcode 项目。在确保所有编译器/链接器标志和环境变量在两个系统之间完全匹配后,我们注意到由 CMake/Xcode 创建的 dylib 稍大一些。仔细检查表明它包含一些额外的导出符号(来自从未引用的模板函数,因此不应该被实例化 - 特定模板在源文件中具有它们的定义和特化,因为我们经常使用显式实例化,尽管在这种情况下它们没有显式实例化)。检查一些目标文件的反汇编也显示出轻微的指令差异。使库在大小和符号上完全匹配的唯一方法是完全匹配编译器标志的顺序。这似乎表明编译器标志之间存在一些依赖于顺序的交互,这似乎是编译器错误或至少记录不充分的行为。
对于这个特定问题,这些是编译器调用:
clang++ -fvisibility=hidden -fvisibility-ms-compat -c foo.cpp -o foo.o
clang++ -fvisibility-ms-compat -fvisibility=hidden -c foo.cpp -o foo.o
这是链接器调用:
clang++ -dynamiclib -o libfoo.dylib foo.o
显示导出的符号:
nm -g libfoo.dylib
显示了差异。我提交了这个LLVM Bug。
是否存在编译器标志排序很重要的有效情况?
【问题讨论】:
-
另请注意,如果您尝试精确匹配二进制大小,如果您包含调试符号 (-g),则执行编译的目录很重要,因为文件路径将包含在对象中文件。