如何在预处理时间可靠地检测clang的版本?

时间:2013-10-15 17:10:47

标签: c++ xcode clang c-preprocessor

显然,与XCode捆绑在一起的clang不尊重上游__clang_major____clang_minor__值,而是报告某种面向XCode用户的版本。

以下是clang的各种MacPorts安装的参考值。他们似乎尊重上游版本标识符。在Linux上测试时,我得到类似的值。

➜  prohibit-clang-3.2  /opt/local/bin/clang++-mp-3.2 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 2

➜  prohibit-clang-3.2  /opt/local/bin/clang++-mp-3.3 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 3

➜  prohibit-clang-3.2  /opt/local/bin/clang++-mp-3.4 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 4

但是,出于某种原因,Apple提供的clang有__clang_major____clang_minor__个版本来跟踪XCode版本,而不是基本的clang版本:

➜  prohibit-clang-3.2 
/Applications/Xcode-4.6.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 4
#define __clang_minor__ 2

➜  prohibit-clang-3.2 
/Applications/Xcode-4.6.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
--version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix

➜  prohibit-clang-3.2 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 5
#define __clang_minor__ 0

➜  prohibit-clang-3.2 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
--version
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix

➜  prohibit-clang-3.2  /usr/bin/clang++ -dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 5
#define __clang_minor__ 0

这看起来非常糟糕,因为这意味着您无法编写如下所示的条件编译行,这些符号编译行将在Apple销售的clang和clang源或发行版软件包中正常构建的clang上正常工作:

#if !defined(__clang__) || (__clang_major__ > 3) || ((__clang_major__ == 3) && (__clang_minor__ > 2))
// Thing that doesn't work for clang-3.2 due to an optimization bug.
#endif

我讨厌需要扩展已经非常糟糕的预处理器检查以考虑两个不同的clang版本控制方案,一个普通版本和一个Apple版本。我甚至不确定如何可靠地发现这是'XCode clang'而不是正常的铿锵声。

有没有人对如何解决这个问题有任何建议?是否有一面旗帜传递给Apple的铿锵声,指示它报告其“真实”版本?或者Apple让我们注定永远无法可靠地使用__clang_major____clang_minor__?这些不是我应该在这里使用的宏吗?

1 个答案:

答案 0 :(得分:4)

如果feature checking macros没有涵盖您需要检查的内容,那么您需要单独处理供应商版本,因为它们可能与开源LLVM版本有非常不同的内容。您可以使用__apple_build_version__检查特定的Apple LLVM版本。

相关问题