CheckSourceCompiles

3.19 版本新增。

此模块提供了一个命令,用于检查给定语言的源代码是否可以构建。

在 CMake 项目中加载此模块,使用

include(CheckSourceCompiles)

命令

此模块提供以下命令

check_source_compiles

检查一次给定语言的源代码是否可以构建

check_source_compiles(
  <lang>
  <code>
  <variable>
  [FAIL_REGEX <regexes>...]
  [SRC_EXT <extension>]
)

此命令会检查一次,以确定在 `<lang>` 语言下,`<code>` 中的源代码是否可以被编译(并链接成可执行文件)。检查结果将存储在 `<variable>` 指定的内部缓存变量中。

参数为

<lang>

要检查的源代码的语言。支持的语言包括:`C`、`CXX`、`CUDA`、`Fortran`、`HIP`、`ISPC`、`OBJC`、`OBJCXX` 和 `Swift`。

版本 3.21 新增:支持 HIP 语言。

版本 3.26 新增:支持 Swift 语言。

<code>

要检查的源代码。这必须是一个完整的程序,就像在一个包含主体块的文件中编写的那样。源代码中使用的所有符号都应该像往常一样在其对应的头文件中声明。

<variable>

内部缓存变量的变量名,用于存储检查结果,成功为布尔真,失败为布尔假。

FAIL_REGEX <regexes>...

如果提供了一个或多个正则表达式模式,则通过检查编译器输出中是否有任何内容与任何指定的正则表达式匹配来确定失败。

SRC_EXT <extension>

默认情况下,用于检查的内部测试源文件将被赋予一个与所请求语言匹配的文件扩展名(例如,C 为 `.c`,C++ 为 `.cxx`,Fortran 为 `.F90` 等)。此选项可用于改用 `.<extension>` 来覆盖此默认行为。

影响检查的变量

在调用此命令之前,可以设置以下变量来修改检查的运行方式

CMAKE_REQUIRED_FLAGS

要传递给编译器的附加标志的空格分隔字符串。`分号分隔的列表` 将不起作用。`CMAKE_<LANG>_FLAGS` 的内容及其相关的特定于配置的 `CMAKE_<LANG>_FLAGS_<CONFIG> 变量会自动置于此变量内容之前的编译器命令之前。

CMAKE_REQUIRED_DEFINITIONS

分号分隔的编译器定义列表,每个定义的形式为 -DFOO-DFOO=bar。还将自动添加对检查命令的 result variable 参数指定的名称的定义。

CMAKE_REQUIRED_INCLUDES

要传递给编译器的头文件搜索路径的分号分隔列表。这些将是唯一使用的头文件搜索路径;将忽略 INCLUDE_DIRECTORIES 目录属性的内容。

CMAKE_REQUIRED_LINK_OPTIONS

3.14 版新增。

要添加到链接命令的选项的分号分隔列表(有关更多详细信息,请参阅 try_compile())。

CMAKE_REQUIRED_LIBRARIES

要添加到链接命令的库的分号分隔列表。这些可以是系统库的名称,也可以是 导入的目标(有关更多详细信息,请参阅 try_compile())。

CMAKE_REQUIRED_LINK_DIRECTORIES

在版本 3.31 中添加。

要传递给链接器的库搜索路径的分号分隔列表(有关更多详细信息,请参阅 try_compile())。

CMAKE_REQUIRED_QUIET

版本 3.1 中新增。

如果此变量评估为布尔真值,则与检查关联的所有状态消息都将被抑制。

CMAKE_TRY_COMPILE_TARGET_TYPE

内部使用 `try_compile() 命令来执行检查,此变量控制它创建的目标类型。如果此变量设置为 `EXECUTABLE`(默认值),则检查会将测试源代码编译并链接成可执行程序。如果设置为 `STATIC_LIBRARY`,则测试源代码将被编译但不会被链接。

示例

示例:基本用法

以下示例演示了如何使用此模块检查 C++ 编译器是否支持特定的语言功能。在本例中,检查验证编译器是否支持 `C++11` lambda 表达式。结果存储在内部缓存变量 `HAVE_CXX11_LAMBDAS` 中。

include(CheckSourceCompiles)

check_source_compiles(CXX "
  int main()
  {
    auto lambda = []() { return 42; };
    return lambda();
  }
" HAVE_CXX11_LAMBDAS)

示例:检查带括号参数的代码

以下示例展示了如何检查 C 编译器是否支持 `noreturn` 属性。代码使用 `括号参数` 提供,以便于处理嵌入的引号。

include(CheckSourceCompiles)

check_source_compiles(C [[
  #if !__has_c_attribute(noreturn)
  #  error "No noreturn attribute"
  #endif
  int main(void) { return 0; }
]] HAVE_NORETURN)

示例:执行不链接的检查

在以下示例中,此模块用于对 Fortran 源代码执行仅编译检查,以确定编译器是否支持 `pure` 过程属性。

include(CheckSourceCompiles)

block()
  set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")

  check_source_compiles(
    Fortran
    "pure subroutine foo()
    end subroutine"
    HAVE_PURE
  )
endblock()

示例:独立检查

在以下示例中,此模块与 `CMakePushCheckState 模块结合使用,以在检查 PostgreSQL `PGVerbosity` 枚举是否包含 `PQERRORS_SQLSTATE`(从 PostgreSQL 12 版本开始可用)时修改所需的库。

include(CheckSourceCompiles)
include(CMakePushCheckState)

find_package(PostgreSQL)

if(TARGET PostgreSQL::PostgreSQL)
  cmake_push_check_state(RESET)
    set(CMAKE_REQUIRED_LIBRARIES PostgreSQL::PostgreSQL)

    check_source_compiles(C "
      #include <libpq-fe.h>
      int main(void)
      {
        PGVerbosity e = PQERRORS_SQLSTATE;
        (void)e;
        return 0;
      }
    " HAVE_PQERRORS_SQLSTATE)
  cmake_pop_check_state()
endif()

另请参阅

  • `CheckSourceRuns` 模块用于检查源代码是否可以构建并运行。