Get Apple clang version and corresponding upstream LLVM version

前端 未结 9 2145
梦如初夏
梦如初夏 2020-12-05 06:25

I want to understand which version of clang Apple installed in my macbook, to see with c++11 and/or c++14 features are available. I typed this command:

clang         


        
相关标签:
9条回答
  • 2020-12-05 06:34

    Wikipedia's Xcode page has a map of Apple to LLVM versions. The LLVM column has the open-source LLVM/Clang version. From this you can look up a language feature in cppreference's chart of compiler support for language features.

    0 讨论(0)
  • 2020-12-05 06:38

    First, I want to say that Daniel Frey's answer is absolutely correct; you really should be using __has_feature, __has_extension, etc. when possible. The Clang Language Extensions page documents the different things you can check for, and that should be your go-to solution.

    That said, sometimes you really do need to check the version. For example, sometimes it is necessary to work around compiler bugs which have been fixed in newer versions, or which only appear in newer versions. Sometimes new functionality is added; for example, prior to clang 9 __builtin_constant_p didn't work correctly with the diagnose_if attribute. Sometimes a feature is added but there is no corresponding check.

    I really wish clang would just expose the upstream version numbers as preprocessor macros so we could reliably handle cases like that, but they don't. You could manually create a map of Apple version numbers to upstream, which is what several other answers have proposed, but that has some pretty obvious drawbacks. For me, the fatal flaw is that it doesn't really work for compilers other than Apple clang; there are a lot of compilers based on clang these days (IBM XL C/C++, some newer PGI/NVIDIA compilers, next-gen Intel C/C++, etc.).

    My work-around is to use feature detection macros to estimate a version number. For example, -Wimplicit-const-int-float-conversion was added in clang 11, so if __has_warning("-Wimplicit-const-int-float-conversion") is true we can assume the upstream clang version is >= 11. Similarly, clang 10 added -Wmisleading-indentation, clang 9 started definining the __FILE_NAME__ preprocessor macro, etc.

    I've created a small header which contains the necessary logic. It's public domain (CC0), and even though it is part of one of my projects (SIMDe) it doesn't depend on anything else from any other files, so you're free to steal it for your own projects without copying all of SIMDe.

    Obviously the file needs a new test for each version of clang, so it does require occasional updates if you need to be able to check for newer compilers, so I'd suggest grabbing the latest version from the SIMDe git repository (I'm not likely to keep this answer up to date), but here is what the checks look like right now:

    #if defined(__clang__) && !defined(SIMDE_DETECT_CLANG_VERSION)
    #  if __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("-Wcast-calling-convention")
    #    define SIMDE_DETECT_CLANG_VERSION 30900
    #  elif __has_warning("-WCL4")
    #    define SIMDE_DETECT_CLANG_VERSION 30800
    #  elif __has_warning("-WIndependentClass-attribute")
    #    define SIMDE_DETECT_CLANG_VERSION 30700
    #  elif __has_warning("-Wambiguous-ellipsis")
    #    define SIMDE_DETECT_CLANG_VERSION 30600
    #  else
    #    define SIMDE_DETECT_CLANG_VERSION 1
    #  endif
    #endif /* defined(__clang__) && !defined(SIMDE_DETECT_CLANG_VERSION) */
    

    I think the biggest problem with this method is actually shared with all other attempts to detect the upstream clang version that I'm aware of: there isn't necessarily a clang release that corresponds to the code in question. As far as I can tell, most compilers based on clang aren't actually based on releases, but rather some random commit (probably whatever is the latest commit for the branch they want to base their work on). That means that, for example, if an issue is was fixed late in the clang $N development cycle, Apple's fork may generally be the same as clang $N but not contain the bug fix. Conversely, maybe Apple will back-port a fix from clang $N+1 and a bug present in clang $N will be fixed in Apple's version.

    0 讨论(0)
  • 2020-12-05 06:44

    If you installed clion, in it's preference-toolchains, you might see 'debugger' as bundled LLDB 7.0.1.

    I believe this is the current Apple clang version. (eg.Apple LLVM version 10.0.1)

    0 讨论(0)
  • 2020-12-05 06:46

    Here is the best listing I've found that correlates Apple's clang versions with the LLVM versions:

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

    Previous versions used to say what LLVM version they corresponded to, but starting with 7.0, Apple decided to no longer do that. They even define the __clang_version__ and related preprocessor macros to indicate the Apple version number, not the LLVM version. So they're useless for this as well.

    Unfortunately, it looks like the only way to see if you have a feature is to try it and check if it works. e.g. 7.0.2 still doesn't have OpenMP enabled by default (although it's enable-able), so I guess it's still 3.6, not 3.7 yet.

    0 讨论(0)
  • 2020-12-05 06:48

    If you use the strings command on the compiler you might get the LLVM version.

    For example if you have the clang version that identifies itself as Apple LLVM version 7.0.2 (clang-700.1.81), the output of strings will have this value:

    LLVM 3.7.0svn
    

    This doesn't appear to work with version Apple LLVM version 7.3.0 (clang-703.0.29)

    0 讨论(0)
  • 2020-12-05 06:51

    As hinted by pkolbus, you can look at the /src/CMakeLists.txt to guess the corresponding Clang version. For example, Apple Clang 800.0.38 and 800.0.42.1 both seem to based on Clang 3.9.0 according to

    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()
    
    0 讨论(0)
提交回复
热议问题