如何在cmake的函数中设置全局变量?

sea*_*ean 14 cmake

我正在写一个CMakeLists.txt来生成文件并编译生成的文件.我创建了一个函数来将一些文件路径字符串添加到全局列表变量.

我的CMakeLists.txt:

set(source_list "nothing")
function(test file_path)
    list(APPEND source_list ${file_path})
endfunction(test)
test(abc.txt)
test(def.txt)
message("At last, the source_list is:\"${source_list}\"")
Run Code Online (Sandbox Code Playgroud)

cmake输出:

At last, the source_list is:"nothing"
Run Code Online (Sandbox Code Playgroud)

有人建议使用宏而不是函数,但我确实需要使用局部变量,所以我需要使用函数而不是宏.

如何在函数test()中正确设置全局变量source_list?cmake不能以简单和正常的方式做到吗?

Din*_*hen 18

PARENT_SCOPE仅适用于父级,如果您有其他想要查看它的非父脚本,它将无法工作.

您需要缓存真正的"全局类"变量.在您的情况下,使用:

SET(source_list  "${source_list}" CACHE INTERNAL "source_list")
Run Code Online (Sandbox Code Playgroud)

  • 它不适用于第二次cmake,因为值已经在缓存中。您必须先清洁后再构建。 (2认同)
  • `INTERNAL` 隐含了 `FORCE`,这意味着:使用 ``FORCE`` 选项覆盖现有条目。 (2认同)

Fra*_*ser 14

您需要使用set而不是list影响父作用域中的变量.

所以用以下list命令替换你的命

set(source_list ${source_list} ${file_path} PARENT_SCOPE)
Run Code Online (Sandbox Code Playgroud)

  • 虽然它不是全局的,兄弟姐妹不会看到。 (4认同)

Max*_*lov 9

另一种方法是使用全局属性.设置后:

set_property(GLOBAL PROPERTY source_list_property "${source_list}")
Run Code Online (Sandbox Code Playgroud)

你可以从任何地方阅读它:

get_property(source_list GLOBAL PROPERTY source_list_property)
Run Code Online (Sandbox Code Playgroud)

我在上面的例子中使用了property(source_list_property)和variable(source_list)的不同名称.也许最好使用相同的名称.但重点是使用属性作为全局变量,而不是命名.

这样的全局属性不在缓存中.


Mar*_*s V 8

基于 Maxim Suslov 的回答,以下代码适用于我遇到的类似问题:

set_property(GLOBAL PROPERTY source_list)
function(add_source)
    get_property(tmp GLOBAL PROPERTY source_list)
    foreach(arg ${ARGV})
        set(tmp "${tmp} ${arg}")
    endforeach()
    set_property(GLOBAL PROPERTY source_list "${tmp}")
endfunction(add_source)

add_source(a_file)
add_source(b_file c_file)

get_property(local_prop GLOBAL PROPERTY source_list)
message("list: ${local_prop}")
Run Code Online (Sandbox Code Playgroud)

函数 add_source 可以从任何子目录中调用。