我们有一套跨平台的 CMake 构建脚本,我们支持使用Visual C++和GCC构建。
我们正在尝试Clang,但我不知道如何使用我们的 CMake 脚本测试编译器是否是 Clang。
我应该测试什么来查看编译器是否是 Clang?我们目前正在分别使用MSVC
和CMAKE_COMPILER_IS_GNU<LANG>
测试 Visual C++ 和 GCC。
我们有一套跨平台的 CMake 构建脚本,我们支持使用Visual C++和GCC构建。
我们正在尝试Clang,但我不知道如何使用我们的 CMake 脚本测试编译器是否是 Clang。
我应该测试什么来查看编译器是否是 Clang?我们目前正在分别使用MSVC
和CMAKE_COMPILER_IS_GNU<LANG>
测试 Visual C++ 和 GCC。
一个可靠的检查是使用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 开始CMAKE_<LANG>_COMPILER_ID
,Apple 提供的 Clang 的值现在是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_CXX_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()
这是针对 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()
你可以测试 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_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
为了避免任何拼写错误问题,我使用不区分大小写的比较,例如:
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
不区分大小写,我在这里尝试了一切但没有成功(CMake 似乎不支持)。