备用标题:为什么我的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。
是否存在编译器标志排序很重要的有效情况?
答案 0 :(得分:1)
微软的编译器以及其他几乎所有人都在传统上在目标文件中具有非常不同的符号可见性模型。前者长期使用C和C ++语言扩展来控制编译器的符号发射,默认情况下不导出符号。
似乎-fvisibility=hidden
和-fvisibility-ms-compat
是互斥的,并且编译器会尊重最后一个在其命令行上看到的内容。
平心而论,-fvisibility-ms-compat
只有很少的文档 - 除了将提交添加到clang
之外。