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

28

我正在编写一个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不能用一种简单正常的方式完成吗?

6个回答

44

PARENT_SCOPE只适用于父级,如果有其他非父级脚本也想看到它,则不起作用。

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

SET(source_list  "${source_list}" CACHE INTERNAL "source_list")

4
因为值已经在缓存中,所以无法在第二次运行cmake时起作用。 在构建之前,您必须清除缓存。 - Maxim Suslov
2
INTERNAL 暗示 FORCE,这意味着:使用FORCE选项来覆盖现有条目。 - Ding-Yi Chen

25

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

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

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

get_property(source_list GLOBAL PROPERTY source_list_property)

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

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


22

你需要使用set而不是list来影响父作用域中的变量。

所以将你的list命令替换为:

set(source_list ${source_list} ${file_path} PARENT_SCOPE)

7
虽然不是全局的,但兄弟姐妹将无法看到。 - 0xbaadf00d
@JoachimW:为什么要将两个答案合并成一个?您好像误解了Stack Overflow的问题/答案模型。我们不会在单个被接受的答案中包含所有解决方案。相反,每个解决方案都应该有一个答案。而答案的质量主要由投票来衡量,好的答案不需要用绿色的接受标记来标记。请撤销这个答案合并。 - Tsyvarev

11

基于 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可以从任何子目录内调用。


4

解决该问题的另一种方法是使用而非函数 - 这样,宏中的所有变量将在调用者的上下文中进行评估。


1

您也可以使用环境变量进行工作。

  SET(ENV{SOURCE_LIST} "$ENV{SOURCE_LIST} newSource")

测试:

  message(STATUS "GLOBAL: $ENV{SOURCE_LIST}")
  -- GLOBAL: newSource /unittest/demo1 /unittest/demo2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接