获取Apple clang版本和相应的上游LLVM版本

use*_*708 61 clang llvm-clang c++11 c++14 c++17

我想了解哪些版本的clang Apple安装在我的macbook中,可以看到c ++ 11和/或c ++ 14的功能.我输入了这个命令:

clang --version

//----response
Apple LLVM version 7.0.0 (clang-700.1.76)     
Target: x86_64-apple-darwin15.0.0    
Thread model: posix
Run Code Online (Sandbox Code Playgroud)

但我无法理解什么(clang-700.1.76)意思.如何将此代码转换为clang版本?

这是您可以检查clang版本http://clang.llvm.org/cxx_status.html中提供的c ++功能的站点.

Mik*_*vis 20

这是我发现的最好的列表,它将Apple的clang版本与LLVM版本相关联:

https://trac.macports.org/wiki/XcodeVersionInfo

以前的版本曾经说过他们对应的LLVM版本,但从7.0开始,Apple决定不再那样做了.他们甚至定义了__clang_version__相关的预处理器宏以指示Apple版本号,而不是LLVM版本.所以他们也没用.

不幸的是,看起来你有一个功能的唯一方法是尝试它并检查它是否有效.例如7.0.2默认情况下仍然没有启用OpenMP(虽然它是可启用的),所以我猜它仍然是3.6,而不是3.7.


Joh*_*ane 18

维基百科的Xcode页面有一个Apple到LLVM版本的地图(至少到AppleClang 800.0.42.1).LLVM列具有开源LLVM/Clang版本.从中您可以在cppreference的语言功能编译器支持图表中查找语言功能.


Fra*_* Yu 10

如图所示pkolbus,您可以查看/src/CMakeLists.txt猜测相应的Clang版本.例如,Apple Clang 800.0.38800.0.42.1似乎都基于Clang 3.9.0

if(NOT DEFINED LLVM_VERSION_MAJOR)
  set(LLVM_VERSION_MAJOR 3)
endif()
if(NOT DEFINED LLVM_VERSION_MINOR)
  set(LLVM_VERSION_MINOR 9)
endif()
if(NOT DEFINED LLVM_VERSION_PATCH)
  set(LLVM_VERSION_PATCH 0)
endif()
if(NOT DEFINED LLVM_VERSION_SUFFIX)
  set(LLVM_VERSION_SUFFIX svn)
endif()
Run Code Online (Sandbox Code Playgroud)


小智 5

看看https://en.wikipedia.org/wiki/Xcode#Toolchain_versions

------------------------------------------------------------------------------------ Xcode cctools[93] ld64[94] LLVM[85] Clang version string[95] 8.3.3 898 278.4 3.9.0svn[85] 8.1.0 (clang-802.0.42)[80] 9.0 900 302.3 4.0.0?[86] 9.0.0 (clang-900.0.37)[80] 9.1 900 302.3.1 4.0.0?[87] 9.0.0 (clang-900.0.38)[80] 9.2 900 305 4.0.0?[88] 9.0.0 (clang-900.0.39.2)[80] 9.3 906 351.8 5.0.2?[89] 9.1.0 (clang-902.0.39.1)[80] 9.3.1 906 351.8 5.0.2?[89] 9.1.0 (clang-902.0.39.1)[80] 9.4 906 351.8 5.0.2?[90] 9.1.0 (clang-902.0.39.2)[80] 9.4.1 906 351.8 5.0.2?[90] 9.1.0 (clang-902.0.39.2)[80] 10.0 921.0.1 409.12 6.0.1?[91] 10.0.0 (clang-1000.11.45.2)[80] 10.1 921.0.1 409.12 6.0.1?[92] 10.0.0 (clang-1000.11.45.5)[80]

例如,Apple CLang 10.x 基于 LLVM 6.0.1。


nem*_*equ 5

首先,我想说丹尼尔·弗雷的回答是绝对正确的;你真的应该使用__has_feature__has_extension等等。如果可能。Clang语言扩展页面记录了您可以检查的不同内容,这应该是您的首选解决方案。

也就是说,有时您确实需要检查版本。例如,有时需要解决已在较新版本中修复的编译器错误,或仅出现在较新版本中的编译器错误。有时会添加新功能;例如,在 clang 9 之前,属性__builtin_constant_p无法正常工作diagnose_if。有时添加了某个功能但没有相应的检查。

我真的希望 clang 将上游版本号公开为预处理器宏,这样我们就可以可靠地处理这样的情况,但他们没有。您可以手动创建 Apple 版本号到上游的映射,这是其他几个答案所提议的,但这有一些非常明显的缺点。对我来说,致命的缺陷是它对 Apple clang 以外的编译器不起作用;现在有很多基于 clang 的编译器(IBM XL C/C++、一些较新的 PGI/NVIDIA 编译器、下一代 Intel C/C++ 等)。

我的解决方法是使用功能检测宏来估计版本号。例如,-Wimplicit-const-int-float-conversion在 clang 11 中添加,因此如果为__has_warning("-Wimplicit-const-int-float-conversion")true,我们可以假设上游 clang 版本 >= 11。类似地,添加了 clang 10 -Wmisleading-indentation、clang 9 开始定义__FILE_NAME__预处理器宏等。

我创建了一个包含必要逻辑的小标头。它是公共域(CC0),尽管它是我的一个项目(SIMDe)的一部分,但它不依赖于任何其他文件中的任何其他内容,因此您可以为自己的项目随意窃取它,而无需复制所有内容SIMDe。

显然,该文件需要对每个版本的 clang 进行新的测试,因此如果您需要能够检查较新的编译器,它确实需要偶尔更新,所以我建议从 SIMDe git 存储库中获取最新版本(我不是可能会保持这个答案是最新的),但检查现在的样子是这样的:

#if defined(__clang__) && !defined(SIMDE_DETECT_CLANG_VERSION)
#  if __has_warning("-Wformat-insufficient-args")
#    define SIMDE_DETECT_CLANG_VERSION 120000
#  elif __has_warning("-Wimplicit-const-int-float-conversion")
#    define SIMDE_DETECT_CLANG_VERSION 110000
#  elif __has_warning("-Wmisleading-indentation")
#    define SIMDE_DETECT_CLANG_VERSION 100000
#  elif defined(__FILE_NAME__)
#    define SIMDE_DETECT_CLANG_VERSION 90000
#  elif __has_warning("-Wextra-semi-stmt") || __has_builtin(__builtin_rotateleft32)
#    define SIMDE_DETECT_CLANG_VERSION 80000
#  elif __has_warning("-Wc++98-compat-extra-semi")
#    define SIMDE_DETECT_CLANG_VERSION 70000
#  elif __has_warning("-Wpragma-pack")
#    define SIMDE_DETECT_CLANG_VERSION 60000
#  elif __has_warning("-Wbitfield-enum-conversion")
#    define SIMDE_DETECT_CLANG_VERSION 50000
#  elif __has_attribute(diagnose_if)
#    define SIMDE_DETECT_CLANG_VERSION 40000
#  elif __has_warning("-Wcomma")
#    define SIMDE_DETECT_CLANG_VERSION 39000
#  elif __has_warning("-Wdouble-promotion")
#    define SIMDE_DETECT_CLANG_VERSION 38000
#  elif __has_warning("-Wshift-negative-value")
#    define SIMDE_DETECT_CLANG_VERSION 37000
#  elif __has_warning("-Wambiguous-ellipsis")
#    define SIMDE_DETECT_CLANG_VERSION 36000
#  else
#    define SIMDE_DETECT_CLANG_VERSION 1
#  endif
#endif /* defined(__clang__) && !defined(SIMDE_DETECT_CLANG_VERSION) */
Run Code Online (Sandbox Code Playgroud)

我认为这种方法的最大问题实际上是与我所知道的所有其他检测上游 clang 版本的尝试共享的:不一定有与相关代码相对应的 clang 版本。据我所知,大多数基于 clang 的编译器实际上并不是基于版本,而是一些随机提交(可能是他们想要基于其工作的分支的最新提交)。这意味着,例如,如果问题在 clang $N 开发周期的后期得到修复,Apple 的分叉通常可能与 clang $N 相同,但不包含错误修复。相反,Apple 可能会向后移植 clang $N+1 中的修复程序,并且 clang $N 中存在的错误将在 Apple 版本中修复。


Dan*_*rey -1

编译器的(Apple)版本号几乎没有用,因为您还需要考虑您的代码是否使用libstdc++或使用libc++(或任何其他标准库)编译 - 以及这些版本的版本。

如果您想测试语言或库功能,最好检查其他定义的值,例如__cplusplus,,,,等。它并不完美,但根据我的经验和支持__cpp_constexpr__cpp_variadic_templates它似乎工作得更好(如果您想要可移植性)所有主要编译器都在改进。

每个 C++ 标准版本都定义了 的值__cplusplus,一些编译器使用中间值来表示“我们已经开始使用 C++14,但我们还没有实现”。需要时用于>=测试。

其他功能测试宏类似,您可以在N4440找到当前版本。但并非所有编译器都实现 N4440。

  • “编译器的版本号大多没用”什么?我想知道我在他们的跟踪器中看到的错误是否已修复。如果我知道这是一个 clang bug(与 constexpr 或其他相关),它怎么**大多没用**?这是一个很大的、没有证据支持的主张 (18认同)
  • @Ven 这是**在这个问题的背景下**的意思,而不是普遍的。当涉及标准库时,版本号对于功能检测来说几乎没有用处,因为编译器版本号不(也不能)包括使用哪个版本的“libstdc++”。此外,由于 Apple 使用与 Clang 不同的版本架构,因此您不能简单地将 Apple 的版本号与 Clang 的错误数据库进行匹配。 (13认同)
  • 被否决是因为它没有回答确定“clang”版本的具体问题。 (3认同)
  • @ray OP 还写道:“我想了解我的 MacBook 中安装了 Apple 的 clang 版本,**查看 c++11 和/或 c++14 功能是否可用**”。对我来说,这似乎是他想要答案的问题,而不仅仅是他的帖子标题。另外,从 Mike 的回答中查看 https://trac.macports.org/wiki/XcodeVersionInfo,很明显,苹果并没有真正记录他们的 Clang 版本与官方 Clang 版本相比是基于什么。我仍在等待如何解决 OP 问题的更好答案。 (3认同)