【问题标题】:How to set the global variable in a function for cmake?如何在cmake的函数中设置全局变量?
【发布时间】:2012-04-19 09:22:48
【问题描述】:

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

【问题讨论】:

    标签: cmake


    【解决方案1】:

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

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

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

    【讨论】:

    • 第二次运行 cmake 时不起作用,因为值已经在缓存中。您必须在构建之前进行清理。
    • INTERNAL 隐含FORCE,这意味着:使用FORCE 选项覆盖现有条目。
    【解决方案2】:

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

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

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

    get_property(source_list GLOBAL PROPERTY source_list_property)
    

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 虽然不是全局的,兄弟姐妹不会看到。
      • @JoachimW:为什么要将两个答案合并到一个答案中?您似乎误解了 Stack Overflow 上的问答模型。我们不倾向于在单一接受的答案中包含所有解决方案。相反,每个解决方案都有一个答案是完美的。并且答案的质量主要通过投票来衡量,好的答案不需要标上绿色的接受标记。请还原此答案合并。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-09
          • 1970-01-01
          • 2014-08-20
          • 1970-01-01
          • 2013-10-21
          相关资源
          最近更新 更多