有谁知道在CMake文件中应用“包含一次”模式的简单方法?在C / C ++中,它通常在头文件的开头和结尾都需要一个#ifdef / #endif对,直到#pragma变得常见为止。当然,可以在CMake中做同样的事情,但是我认为如果不需要显式的条件语句,那会很好。
重新版本:似乎return()命令应该这样做。我会定义一个这样的宏:
macro(include_once)
if (INCLUDED_${CMAKE_CURRENT_LIST_FILE})
return()
endif()
set(INCLUDED_${CMAKE_CURRENT_LIST_FILE} true)
endmacro()
Run Code Online (Sandbox Code Playgroud)
在文件开头使用宏,不带任何参数。因为它是一个宏,所以返回的是文件的include命令,而不是宏本身。
请注意,创建的变量的名称为奇数,但CMake似乎接受此名称。
我曾经使用其他人建议的逻辑作为解决方案。然后我了解到 cmake 内置了这个功能。
看看include_guard()。我相信这会做你想做的。
防止包含多个模块的最简单防护模式是
if(<something-which-is-defined-in-your-module>)
return()
endif()
Run Code Online (Sandbox Code Playgroud)
例如,如果您的CMake模块定义了一个函数foo_func,则可以使用以下防护:
if(COMMAND foo_func)
return()
endif()
Run Code Online (Sandbox Code Playgroud)
根据模块中定义的内容,该模块可能需要保护,也可能不需要多次包含。
在许多简单的情况下,不需要防护措施:即使多次包含该模块的代码,它们也可以工作。
但是在某些其他情况下,错误的保护可能会中断受保护模块的使用。
模块定义一个函数或宏:不需要防护。
CMake允许多次定义函数和宏。
模块定义了一个常量变量:不需要 guard 。
与功能一样,CMake允许多次定义变量。
但是,如果在这种情况下使用了防护,则应检查variable而不是函数:
if(foo_var)
return()
endif()
Run Code Online (Sandbox Code Playgroud)
这是因为函数具有全局可见性,而变量具有局部可见性。也就是说,如果您的模块将包含在其他子树中,则该功能在该子树中将已经可见,而变量不是。
模块通过以下方式定义全局变量set(CACHE):仅当变量定义为时才需要保护set(CACHE INTERNAL)。
通过例如set(CACHE STRING)或find_library不需要防护定义的变量。
一个模块定义了全局属性:需要守护。
请注意,如果您的模块使用简单(而非CACHE)变量作为全局变量,则它不能在多个子树中工作,因此,警惕是
if(foo_var)
message(SEND_ERROR "Module <...> cannot be included twice")
endif()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1598 次 |
| 最近记录: |