23

我正在编写一个 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}\"")

cmake 输出:

At last, the source_list is:"nothing"

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

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

4

5 回答 5

35

PARENT_SCOPE 仅适用于父级,如果您有其他非父级脚本也想查看它,它将不起作用。

您需要缓存真正的“类全局”变量。在您的情况下,请使用:

SET(source_list  "${source_list}" CACHE INTERNAL "source_list")
于 2014-08-05T03:05:49.110 回答
22

您需要使用set而不是list影响父范围中的变量。

因此,将您的list命令替换为:

set(source_list ${source_list} ${file_path} PARENT_SCOPE)
于 2012-04-05T16:25:05.380 回答
22

另一种方法是使用全局属性。一旦你设置它:

set_property(GLOBAL PROPERTY source_list_property "${source_list}")

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

get_property(source_list GLOBAL PROPERTY source_list_property)

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

此类全局属性不在缓存中。

于 2017-09-25T19:54:56.810 回答
10

基于 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}")

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

于 2017-11-29T10:30:02.987 回答
4

解决此问题的另一种方法是使用macro而不是function- 这样宏内部的所有变量都将在调用者的上下文中进行评估。

于 2020-02-18T08:22:07.880 回答