【问题标题】:CMake: access variable in defining scope from within a functionCMake:从函数内定义范围中的访问变量
【发布时间】:2021-12-22 23:53:24
【问题描述】:

我在 cmake 中创建了一个带有子项目的项目。在子项目中,我有一个函数想要从其定义范围(而不是父项目范围)访问变量。

这是我的文件夹结构:

/project
|-- CMakeLists.txt
'-- /sub
    '-- CMakeLists.txt

外部 CMakeLists.txt:

project(mainproject)
cmake_minimum_required(VERSION 3.17)
add_subdirectory(sub)
message("in parent scope: ${V}")
test()

内部 CMakeLists.txt:

project(subproject)
cmake_minimum_required(VERSION 3.17)
set(V "hello")
message("defining scope: ${V}")

function(test)
    message("function scope: ${V}")
endfunction()

我得到的输出:

defining scope: hello
parent scope: 
function scope: 
-- Configuring done
-- Generating done

我的怀疑是 cmake 根本不支持闭包,但是文档中有这个页面: CMAKE_CURRENT_FUNCTION_LIST_DIR

set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")

function(foo)
  configure_file(
    "${_THIS_MODULE_BASE_DIR}/some.template.in"
    some.output
  )
endfunction()

这几乎完全是我的用例,也是我所做的,但它不起作用。

我在这里错过了什么?

请注意,我可以使用set(V "hello" PARENT_SCOPE),但我不想污染父作用域。

任何帮助表示赞赏!

【问题讨论】:

    标签: function cmake closures


    【解决方案1】:

    CMake 中没有“闭包”语义。任何变量的取消引用都使用 当前范围 中的变量。也就是说,如果您从顶级 CMakeLists.txt 调用 test 函数,则会在该脚本的范围内搜索变量 V,而不是从定义给定函数的 sub/CMakeLists.txt 的范围内搜索。

    只有像CMAKE_CURRENT_FUNCTION_LIST_DIRCMAKE_CURRENT_FUNCTION 这样的特殊变量是该规则的例外:它们根据它们被取消引用的位置(文件、行、函数)进行扩展。

    让你困惑的代码示例

    set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
    
    function(foo)
      configure_file(
        "${_THIS_MODULE_BASE_DIR}/some.template.in"
        some.output
      )
    endfunction()
    

    适用于 CMake 模块,例如 foo.cmake

    模块包含在 include 命令中:

    include(foo)
    ...
    foo()
    

    add_subdirectory 不同,它不引入范围(有关变量范围的更多信息是here)。 所以变量_THIS_MODULE_BASE_DIR对于函数foo的调用者是可见的。 (如果另一个模块使用相同的变量名,那么一个变量会默默地重新定义另一个)。


    为了使您的代码能够正常工作,您需要将V 变量对函数的调用者可见。例如,您可以使用 PARENT 或 CACHE 选项设置变量,或者使用全局属性而不是变量。

    或者,您可以将test 函数的定义从sub/CMakeLists.txt 移动到模块test.cmake,并通过include 将该模块包含在顶级CMakeLists.txt 中。

    【讨论】:

      猜你喜欢
      • 2014-05-29
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 2012-01-13
      • 1970-01-01
      相关资源
      最近更新 更多