简体   繁体   English

在CMake中,如何测试编译器是否为Clang?

[英]In CMake, how can I test if the compiler is Clang?

We have a set of cross-platform CMake build scripts , and we support building with Visual C++ and GCC .我们有一套跨平台的 CMake 构建脚本,我们支持使用Visual C++GCC 构建

We're trying out Clang , but I can't figure out how to test whether or not the compiler is Clang with our CMake script.我们正在尝试Clang ,但我无法弄清楚如何使用我们的 CMake 脚本测试编译器是否为 Clang 。

What should I test to see if the compiler is Clang or not?我应该测试什么来查看编译器是否为 Clang? We're currently usingMSVC and CMAKE_COMPILER_IS_GNU<LANG> to test for Visual C++ and GCC, respectively.我们目前正在使用MSVCCMAKE_COMPILER_IS_GNU<LANG>分别测试 Visual C++ 和 GCC。

A reliable check is to use the CMAKE_<LANG>_COMPILER_ID variables.可靠的检查是使用CMAKE_<LANG>_COMPILER_ID变量。 Eg, to check the C++ compiler:例如,要检查 C++ 编译器:

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  # using Clang
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  # using GCC
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  # using Intel C++
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  # using Visual Studio C++
endif()

These also work correctly if a compiler wrapper like ccache is used.如果使用像ccache这样的编译器包装器,这些也能正常工作。

As of CMake 3.0.0 the CMAKE_<LANG>_COMPILER_ID value for Apple-provided Clang is now AppleClang .从 CMake 3.0.0 开始,Apple 提供的 Clang 的CMAKE_<LANG>_COMPILER_ID值现在是AppleClang To test for both the Apple-provided Clang and the regular Clang use the following if condition:要测试 Apple 提供的 Clang 和常规 Clang,请使用以下 if 条件:

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  # using regular Clang or AppleClang
endif()

Also see the AppleClang policy description .另请参阅AppleClang 策略说明

CMake 3.15 has added support for both the clang-cl and the regular clang front end. CMake 3.15添加了对clang-cl和常规 clang 前端的支持。 You can determine the front end variant by inspecting the variable CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT :您可以通过检查变量CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT来确定前端变体:

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
    # using clang with clang-cl front end
  elseif (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
    # using clang with regular front end
  endif()
endif()

This is a slightly more detailed answer for cmake newbies, modified from sakra's answer.这是针对cmake新手的稍微详细一点的回答,修改自sakra的回答。 The minimum version of 3.1 seems to be important as it changes the way CMake processes the quoted "MSVC" string (according to policy CMP0054). 3.1 的最低版本似乎很重要,因为它改变了 CMake 处理引用的“MSVC”字符串的方式(根据策略 CMP0054)。

cmake_minimum_required(VERSION 3.1)
project(MyProject CXX)

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  MESSAGE("Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  MESSAGE("GNU")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
  MESSAGE("Intel")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

We have a set of cross-platform CMake build scripts , and we support building with Visual C++ and GCC .我们有一套跨平台的 CMake 构建脚本,我们支持使用Visual C++GCC构建。

We're trying out Clang , but I can't figure out how to test whether or not the compiler is Clang with our CMake script.我们正在尝试Clang ,但我不知道如何使用我们的 CMake 脚本测试编译器是否是 Clang 。

What should I test to see if the compiler is Clang or not?我应该测试什么来查看编译器是否是 Clang? We're currently usingMSVC and CMAKE_COMPILER_IS_GNU<LANG> to test for Visual C++ and GCC, respectively.我们目前分别使用MSVCCMAKE_COMPILER_IS_GNU<LANG>来测试 Visual C++ 和 GCC。

If your cmake_minimum_required VERSION is less than 3.1, then you have to use quoted variable to determine compiler, if together with STREQUAL command, ie如果您的 cmake_minimum_required VERSION 小于 3.1,那么您必须使用带引号的变量来确定编译器,如果与STREQUAL命令一起使用,即

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

Or, if you don't like quoted stuff, you can use MATCHES command:或者,如果你不喜欢引用的东西,你可以使用MATCHES命令:

if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  MESSAGE("MSVC")
endif()

And if you specify cmake_minimum_required VERSION >= 3.1, then you can happily use STREQUAL without quotes:如果您指定 cmake_minimum_required VERSION >= 3.1,那么您可以愉快地使用不带引号STREQUAL

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

the cmake 3.1 version issue, is documented here: https://cmake.org/cmake/help/latest/policy/CMP0054.html cmake 3.1 版本问题记录在此处: https://cmake.org/cmake/help/latest/policy/CMP0054.html

Just to avoid any misspelling problem, I am using Case-insensitive compare, like:为了避免任何拼写错误问题,我使用不区分大小写的比较,例如:

string( TOLOWER "${CMAKE_CXX_COMPILER_ID}" COMPILER_ID )
if (COMPILER_ID STREQUAL "clang")
    set(IS_CLANG_BUILD true)
else ()
    set(IS_CLANG_BUILD false)
endif ()

For making the regex of MATCHES case-insensitive, I tried everything here without success (doesn't seem to be supported in CMake).为了使MATCHES的正则表达式不区分大小写,我在这里尝试了所有方法但没有成功(CMake 似乎不支持)。

You can test for Clang and it's frontends like this:您可以测试 Clang,它的前端是这样的:

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") # clang-cl
    # ...
  elseif (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU") # clang native
    # ...
  endif()
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") # both
    # ...
endif()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM