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

问题描述 投票:0回答:5

我们有一套跨平台的CMake构建脚本,我们支持用Visual C++GCC构建。

我们正在尝试 Clang,但我不知道如何用我们的 CMake 脚本测试编译器是否是 Clang。

我应该测试什么来查看编译器是否是 Clang?我们目前正在使用

MSVC
CMAKE_COMPILER_IS_GNU<LANG>
分别测试 Visual C++ 和 GCC。

c++ c cmake clang
5个回答
319
投票

可靠的检查是使用

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 这样的编译器包装器,这些也可以正常工作。

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

5
投票

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

2
投票

如果你的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()

cmake 3.1 版本问题,在此处记录:https://cmake.org/cmake/help/latest/policy/CMP0054.html


1
投票

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

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 似乎不支持)。


1
投票

您可以像这样测试 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()

CMAKE_CXX_COMPILER_FRONTEND_VARIANT 需要 CMake v3.14+。

© www.soinside.com 2019 - 2024. All rights reserved.