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

n9vozmp4  于 2022-11-24  发布在  其他
关注(0)|答案(6)|浏览(507)

我正在编写一个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?难道不能用一种简单而正常的方式来做吗?

gz5pxeao

gz5pxeao1#

PARENT_SCOPE仅用于父脚本,如果您有其他非父脚本也希望看到它,它将不起作用。
您需要缓存真正的“类似全局的”变量用途:

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

9o685dep2#

您需要使用set而不是list来影响父作用域中的变量。
因此,请将您的list命令替换为:

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

cyej8jka3#

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

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

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

get_property(source_list GLOBAL PROPERTY source_list_property)

我在上面的例子中使用了不同的名字给属性(source_list_property)和变量(source_list)。也许使用相同的名字更好。但重点是使用属性作为全局变量,而不是命名。
此类全局属性不在缓存中。

cygmwpex

cygmwpex4#

根据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可以从任何子目录中调用。

abithluo

abithluo5#

解决此问题的另一种方法是使用macro而不是function-这样,宏中的所有变量都将在调用方的上下文中求值。

mwg9r5ms

mwg9r5ms6#

您也可以使用环境变量。

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

测试项目:

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

相关问题