如何在预处理时可靠地检测 clang 的版本
How can I reliably detect the version of clang at preprocessing time?
显然,与 Xcode 捆绑在一起的 clang 不尊重上游__clang_major__
和__clang_minor__
值,而是报告某种面向 Xcode 用户的版本。
以下是各种MacPorts安装的clang的值,以供参考。它们似乎尊重上游版本标识符。在 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具有跟踪Xcode版本的__clang_major__
和__clang_minor__
版本,而不是基本的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 叮当声"而不是正常的叮当声。
有没有人对如何解决这个问题有任何建议?是否有一个标志可以传递给Apple的clang,指示它报告其"真实"版本?还是苹果注定了我们永远无法可靠地使用__clang_major__
和__clang_minor__
?这些不是我应该在这里使用的宏吗?
如果功能检查宏没有涵盖您需要检查的内容,那么您确实需要单独处理供应商版本,因为它们可能与开源 LLVM 版本具有非常不同的内容。您可以使用__apple_build_version__
来检查特定的 Apple LLVM 版本。
相关文章:
- 使用CMake检测支持的C++标准
- 奇怪的结构&GCC&clang(void*返回类型)
- 当套接字连接断开时检测C/C++Unix
- 数据成员SFINAE的C++17测试:gcc vs clang
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- C/C++预处理器是否可以检测一些编译器选项
- WMI检测进程创建事件-c++
- 如何检测 Clang AST C++中的静态函数
- Clang 无法检测到初始化并给出错误
- cmake 将 clang-cl 检测为 clang
- Clang 无法在赋值运算符/复制构造函数中检测到未初始化的类成员
- 使用预处理器检测 MSVC,而不检测 clang-cl、icl
- 使用 Clang 检测进行基于时间的分析
- Clang - 检测头文件何时完成
- 如何在 clang 消毒器发现错误时终止 clang 检测程序
- Clang 无法检测到未定义的行为
- 为什么在模板方法的 clang 中检测到不完整的类型
- 如何在预处理时可靠地检测 clang 的版本
- Clang 3.5:使用 SFINAE 检测 gobal 函数不存在