71

我想了解我的 macbook 中安装了哪个版本的 clang Apple,以查看可用的 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

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

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

4

10 回答 10

29

维基百科的 Xcode 页面有一张 Apple 到 LLVM 版本的地图。LLVM 列具有开源 LLVM/Clang 版本。从这里您可以在 cppreference 的语言特性编译器支持图表中查找语言特性

于 2017-09-16T23:12:43.270 回答
24

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

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

以前的版本曾经说他们对应的是什么 LLVM 版本,但从 7.0 开始,Apple 决定不再这样做。他们甚至定义了__clang_version__相关的预处理器宏来指示 Apple 版本号,而不是 LLVM 版本。因此,它们对此也毫无用处。

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

于 2016-03-15T00:29:59.767 回答
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()
于 2017-01-04T18:59:50.147 回答
6

看看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。

于 2019-03-20T22:21:51.417 回答
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")为真,我们可以假设上游 clang 版本 >= 11。类似地,添加了 clang 10 -Wmisleading-indentation,clang 9 开始定义__FILE_NAME__预处理器宏,等等。

我创建了一个包含必要逻辑的小标题。它是公共领域 (CC0),即使它是我的一个项目 ( 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) */

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

于 2020-10-12T20:45:48.147 回答
3

可以尝试使用--verbose选项编译一些文件。

例如:c++ --verbose -c test1.cpp

Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
 "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.10.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name test1.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 253.9 -v -dwarf-column-info -coverage-file /Users/az/ctest/test1.cpp -resource-dir /Library/Developer/CommandLineTools/usr/bin/../lib/clang/7.0.2 -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /Users/az/ctest -ferror-limit 19 -fmessage-length 130 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.10.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o test1.o -x c++ test1.cpp
clang -cc1 version 7.0.2 based upon LLVM 3.7.0svn default target x86_64-apple-darwin14.5.0

它确实打印 LLVM svn 版本(在我们的示例中为 3.7.0)

于 2017-07-14T15:10:51.823 回答
1

如果你在编译器上使用 strings 命令,你可能会得到 LLVM 版本。

例如,如果您的 clang 版本将自己标识为Apple LLVM 版本 7.0.2 (clang-700.1.81),则字符串的输出将具有以下值:

LLVM 3.7.0svn

这似乎不适用于Apple LLVM 版本 7.3.0 (clang-703.0.29)

于 2016-03-30T13:59:05.237 回答
0

如果你安装了 clion,在它的preference-toolchains中,你可能会看到 'debugger' 作为捆绑的 LLDB 7.0.1

我相信这是当前的 Apple clang 版本。(例如Apple LLVM 10.0.1 版)

于 2019-03-29T04:44:13.527 回答
0

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

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

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

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

于 2015-11-09T17:22:48.673 回答
0

作为您的终端输出

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

第一行“ Apple LLVM version 7.0.0 (clang-700.1.76)”表示:您Xcode7.1的嵌入Clang7.0.0Clang7.0.0标识符:)clang-700.1.76

从这个网站,我知道你的 Clang 版本是7.0.0。如果 Clang 版本是 >= Clang5.0,则该 Clang 支持 C++11 或 C++14

于 2022-01-13T14:55:16.260 回答