更新从子目录CMakeLists.txt文件调用的.cmake函数中顶级CMakeLists.txt中定义的列表

vc6uscn9  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(112)

我尝试使用一个.cmake文件来更新一个全局列表,以收集所有的库名称,并使用该列表来链接顶级CMakeLists.txt文件中的所有库,但不幸的是,在最后我看到列表是空的。请参阅下面的CMakeLists.txt和.cmake调用:

ROOOT
|
---> CMakeLists.txt
     This file creates an empty list
     set(global_list "")
|
---> sub_dir1
        |
        ---> CMakeLists.txt
             This file includes a build.cmake file
        ---> build.cmake
             This file defines a cmake function to update the global_list
             function(update_list)
                list(APPEND global_list ${lib_name})
                set(global_list ${global_list} PARENT_SCOPE)
             endfunction()
---> sub_dir2
        |
        ---> CMakeLists.txt
             This file calls update_list function to send the lib name as an input
             update_list(lib_sub_dir2)
---> sub_dir3
        |
        ---> CMakeLists.txt
             This file calls update_list function to send the lib name as an input
             update_list(lib_sub_dir3)
---> sub_dir4
        |
        ---> CMakeLists.txt
             This file calls update_list function to send the lib name as an input
             update_list(lib_sub_dir4)

最后,当根级别的CMakeLists.txt文件打印global_list时,它显示为空。
要求:global_list应包含lib_sub_dir2、lib_sub_dir3、lib_sub_dir4

xqk2d5yq

xqk2d5yq1#

这里的问题是变量的作用域。每个通过add_subdirectory添加的变量和每个cmake function()调用都会引入一个新的变量作用域。祖先作用域的变量是可读的,但是如果你写一个变量,你是在使用当前作用域中的变量。将信息传递给父作用域的唯一方法是使用set(VAR_NAME value PARENT_SCOPE)
但是,在使用add_subdirectory时,使用此命令并不是很好的维护,因为您需要记住在每个示例中都使用set(... PARENT_SCOPE)
不过,你可以简单地引入一个自己的全局cmake属性。

#introduce the property
set_property(GLOBAL PROPERTY GLOBAL_LIST)

# add "new_element"
set_property(GLOBAL APPEND PROPERTY GLOBAL_LIST new_element)

# store the current value of the GLOBAL_LIST in the GLOBAL_LIST_VALUE variable
get_property(GLOBAL_LIST_VALUE GLOBAL PROPERTY GLOBAL_LIST)

在顶层CMakeLists.txt中引入全局属性,您将能够使用上面的命令从任何地方添加属性并读取属性的当前值。

相关问题