有没有人知道一种简单的方法来应用"包含一次" 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()
在文件开头使用宏,不带任何参数。因为它是一个宏,所以返回来自文件的include命令,而不是来自宏本身。
请注意,创建的变量有一个奇怪的名称,但CMake似乎接受了这个。
答案 0 :(得分:4)
针对多个模块的最简单的保护模式将是
if(<something-which-is-defined-in-your-module>)
return()
endif()
例如,如果你的CMake模块定义了一个函数foo_func
,你可以使用这个警卫:
if(COMMAND foo_func)
return()
endif()
依赖于模块中定义的内容,模块可能需要再次进行多次包含保护。
在许多简单的情况下,不需要 :即使包含多次,模块的代码也能正常工作。
但在其他一些情况下,错误的保护可能会破坏受保护模块的使用。
模块定义功能或宏:后卫不需要。
CMake允许多次定义函数和宏。
模块定义常量变量:guard 不需要。
与函数一样,CMake允许多次定义变量。
但是如果你在这种情况下使用后卫,它应该检查变量,而不是函数:
if(foo_var)
return()
endif()
这是因为函数具有全局可见性,但变量具有本地可见性。也就是说,如果您将模块包含在其他子树中,该函数将在该子树中可见,但该变量不是。
模块通过set(CACHE)
定义全局变量:仅当变量定义为set(CACHE INTERNAL)
时才需要 。
通过例如set(CACHE STRING)
或find_library
定义的变量不需要警卫。
模块定义全局属性:guard 需要。
注意,如果你的模块使用简单的(不是 CACHE )变量作为全局变量,它不能在多个子树中工作,所以后卫应该是
if(foo_var)
message(SEND_ERROR "Module <...> cannot be included twice")
endif()
答案 1 :(得分:2)
我曾经使用其他人建议的逻辑作为解决方案。然后我了解到cmake内置了此功能。
看看include_guard()。我相信这会做您想要的。