cmake文件是否包含一次包含命令?

Ofr*_*sky 6 cmake

有谁知道在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似乎接受此名称。

Joh*_*cha 8

我曾经使用其他人建议的逻辑作为解决方案。然后我了解到 cmake 内置了这个功能。

看看include_guard()。我相信这会做你想做的。

  • 请注意,include_guard 需要 cmake >= 3.10,因此在使用它时应添加最低版本 3.10。 (3认同)

Tsy*_*rev 5

防止包含多个模块的最简单防护模式是

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)

您实际上需要警卫吗?

根据模块中定义的内容,该模块可能需要保护,也可能不需要多次包含。

在许多简单的情况下,不需要防护措施:即使多次包含该模块的代码,它们也可以工作。

但是在某些其他情况下,错误的保护可能会中断受保护模块的使用。

  1. 模块定义一个函数不需要防护。

    CMake允许多次定义函数和宏。

  2. 模块定义了一个常量变量:不需要 guard 。

    与功能一样,CMake允许多次定义变量。

    但是,如果在这种情况下使用了防护,则应检查variable而不是函数:

    if(foo_var)
        return()
    endif()
    
    Run Code Online (Sandbox Code Playgroud)

    这是因为函数具有全局可见性,而变量具有局部可见性。也就是说,如果您的模块将包含在其他子树中,则该功能在该子树中将已经可见,而变量不是。

  3. 模块通过以下方式定义全局变量set(CACHE)仅当变量定义为时才需要保护set(CACHE INTERNAL)

    通过例如set(CACHE STRING)find_library不需要防护定义的变量。

  4. 一个模块定义了全局属性需要守护。

请注意,如果您的模块使用简单(而非CACHE)变量作为全局变量,则它不能在多个子树中工作,因此,警惕是

    if(foo_var)
        message(SEND_ERROR "Module <...> cannot be included twice")
    endif()
Run Code Online (Sandbox Code Playgroud)