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

我们有一组跨平台cmake构建脚本,并且我们支持使用Visual C++海湾合作委员会进行构建。

我们正在尝试铿锵,但我不知道如何测试编译器是否与我们的cmake脚本保持一致。

我应该测试什么来判断编译器是否正常?我们目前正在使用MSVCCMAKE_COMPILER_IS_GNU<LANG>来分别测试Visual C++和GCC.

100982 次浏览

可靠的检查是使用CMAKE_<LANG>_COMPILER_ID变量。例如,检查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()

如果使用像高速缓存这样的编译器包装,它们也可以正常工作。

从CMake 3.0.0开始,Apple提供的Clang的CMAKE_<LANG>_COMPILER_ID值现在AppleClang。要测试Apple提供的Clang和常规Clang,请使用以下IF条件:

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

另请参阅AppleClang策略说明

CMake3.15增加了对叮当声和常规Clang前端的支持。可通过检查变量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()

只是为了避免任何拼写错误的问题,我使用大小写不敏感的比较,如:

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

为了使MATCHES的正则表达式不区分大小写,我尝试了ABC_1_的所有方法,但都没有成功(cmake似乎不支持)。

对于CMake新手来说,这是一个稍微更详细的答案,由Sakra的答案修改而来。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()

如果您的CMake_所需的最低_版本低于3.1,则必须使用带引号的变量来确定编译器,如果与STREQUAL命令一起使用,即

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

或者,如果您不喜欢引用的内容,可以使用MATCHES命令:

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

如果您指定cmake_最小_所需版本>;=3.1,那么您可以愉快地使用_不带引号的ABC_0:

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

CMake 3.1版本问题记录如下:https://cmake.org/cmake/help/latest/policy/CMP0054.html

你可以测试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()