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

pgvzfuti  于 2022-11-11  发布在  其他
关注(0)|答案(5)|浏览(256)

我们有一组cross-platform CMake build scripts,并且我们支持使用Visual C++GCC进行构建。
我们正在尝试Clang,但是我不知道如何用CMake脚本测试编译器是否是Clang。
我应该测试什么来查看编译器是否是Clang?我们目前正在使用MSVCCMAKE_COMPILER_IS_GNU<LANG>分别测试Visual C++和GCC。

3z6pesqy

3z6pesqy1#

一个可靠的检查是使用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()

如果使用ccache这样的编译器 Package ,这些也可以正常工作。
从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策略描述。
CMake 3.15增加了对clang-cl和常规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()
uqzxnwby

uqzxnwby2#

这是对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()
c0vxltue

c0vxltue3#

如果你的cmake_minimum_required VERSION低于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_minimum_required VERSION〉= 3.1,那么你就可以使用STREQUAL而不用引号:

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

cmake3.1版本问题记录在以下位置:https://cmake.org/cmake/help/latest/policy/CMP0054.html

uurv41yg

uurv41yg4#

为了避免任何拼写错误问题,我使用了不区分大小写的比较,例如:

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的正则表达式不区分大小写,我尝试了here的所有方法,但都没有成功(CMake似乎不支持)。

egdjgwm8

egdjgwm85#

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

相关问题