【问题标题】:Get Apple clang version and corresponding upstream LLVM version获取 Apple clang 版本和对应的上游 LLVM 版本
【发布时间】:2016-02-09 17:44:06
【问题描述】:

我想了解我的 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++ 功能的站点

【问题讨论】:

  • 显然,它曾经报告它所基于的上游 LLVM 版本:Xcode clang versions,但您发现它不再如此。我猜是 3.6 或 3.7。
  • 重命名“获取Apple clang版本和对应的上游LLVM版本”总结一下

标签: c++11 clang c++14 llvm-clang c++17


【解决方案1】:

维基百科的 Xcode 页面有 a map of Apple to LLVM versions。 LLVM 列具有开源 LLVM/Clang 版本。从这里您可以在 cppreference 的chart of compiler support for language features 中查找语言功能。

【讨论】:

    【解决方案2】:

    这是我发现的将 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。

    【讨论】:

      【解决方案3】:

      正如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()
      

      【讨论】:

      • 哪个/src/CMakeLists.txt?
      • @Walter 来自 Clang 的那个。我已经链接到答案中的两个示例。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        也就是说,有时您确实需要检查版本。例如,有时需要解决已在较新版本中修复或仅在较新版本中出现的编译器错误。有时会添加新功能;例如,在 clang 9 __builtin_constant_p didn't work correctly with the diagnose_if attribute 之前。有时添加了一个特性但没有相应的检查。

        我真的希望 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__ 预处理器宏等。

        我创建了包含必要逻辑的a small header。它是公共领域 (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) */
        

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

        【讨论】:

          【解决方案6】:

          可以尝试编译带有--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)

          【讨论】:

          【解决方案7】:

          如果你在编译器上使用 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)

          【讨论】:

          • 当前 Apple clang 字符串仅包含二进制名称。或者我在这里错过了什么? gist.github.com/webmaster128/73dee3783694b04987290e5b120aa3e5
          • @SimonWarta /usr 中的 Xcode 命令行工具实际上只是 Xcode 包中安装的真实工具的快捷方式。使用strings "$(xcrun --find clang)" | grep LLVM
          【解决方案8】:

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

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

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

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

          【讨论】:

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

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

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

          【讨论】:

            【解决方案10】:

            作为您的终端输出

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

            从这个website,我知道你的Clang 版本是7.0.0。 如果 Clang 版本 >= Clang5.0, that Clang support C++11 or C++14

            【讨论】:

              猜你喜欢
              • 2014-12-12
              • 2016-07-15
              • 1970-01-01
              • 2021-05-27
              • 1970-01-01
              • 2011-05-22
              • 1970-01-01
              • 1970-01-01
              • 2011-11-22
              相关资源
              最近更新 更多