cmake:include、include_guard

  • Post author:
  • Post category:其他

include

  • 说到cmake,可能最先想到的就是CmakeLists.txt文件,但是在很多情况下,也会看到.cmake文件。那么,.cmake是干什么的呢?
    • .cmake文件是一个模块文件,可以被include到CMakeLists.txt中
    • .cmake文件里包含了一些cmake命令和一些宏/函数,当CMakeLists.txt包含该.cmake文件时,当编译运行时,该.cmake里的一些命令就会在该包含处得到执行,并且在包含以后的地方能够调用该.cmake里的一些宏和函数。
  • include可以从文件或模块加载并运行CMake代码。
  • include指令一般用于语句的复用,也就是说,如果有一些语句需要在很多CMakeLists.txt文件中使用,为避免重复编写,可以将其写在.cmake文件中,然后在需要的CMakeLists.txt文件中进行include操作就行了
include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                      [NO_POLICY_SCOPE])

虽然,有不少的可选参数,但是一般情况下,都是直接写:

include(file|module)
字段 意义
< file / module> 文件名(一般是相对路径或者绝对路径)/模块名
OPTIONAL 可选,这样如果文件不存在,则不会引发错误。
RESULT_VARIABLE 基本上不用:如果给了RESULT_VARIABLE变量,变量将被设置为完整的文件名,如果失败,将被设置为NOTFOUND。

include_guard

3.10新版功能。

为CMake当前正在处理的文件提供一个包含保护。

include_guard([DIRECTORY|GLOBAL])

为当前CMake文件设置一个include保护(参见CMAKE_CURRENT_LIST_FILE变量文档)。

如果当前文件已经在适用范围内被处理(见下文),则CMake将在include_guard()命令所在的位置结束对当前文件的处理。它提供的功能类似于源代码头文件中常用的include保护或#pragma once指令。如果当前文件之前已经在适用范围内处理过,其效果就好像已经调用了return()。不要从当前文件中定义的函数内部调用此命令。

可以提供一个可选参数来指定保护的范围。该选项的可能值为:

  • DIRECTORY:
    • 包含保护应用于当前目录及其下面。
    • 该文件只会在此目录范围内被包含一次,但可能会被此目录之外的其他文件再次包含(即父目录或未被add_subdirectory()或include()从当前文件或其子文件拉入的另一个目录)。
  • GLOBAL:包含保护全局应用于整个构建。无论作用域如何,当前文件只被包含一次。

如果没有给出参数,include_guard具有与变量相同的作用域,这意味着如果内部函数作用域不存在,则包含保护作用域由最近的函数作用域或当前目录隔离。在这种情况下,命令行为相同:

if(__CURRENT_FILE_VAR__)
  return()
endif()
set(__CURRENT_FILE_VAR__ TRUE)