I am trying to use a .cmake file to update a global list to collect all the library names and use that list to link all the libraries from the top-level CMakeLists.txt file but unfortunately at the end I see the list is empty. Please see the CMakeLists.txt and .cmake calls in below:
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)
At the end when the root level CMakeLists.txt file prints the global_list it shows empty.
Requirement: global_list should contain lib_sub_dir2, lib_sub_dir3, lib_sub_dir4
The problem here is the scope of variables. Every subdirectory added via add_subdirectory
and every call of a cmake function()
introduces a new variable scope. Variables of ancestor scopes are readable, but if you write a variable, you're working with a variable in the current scope. The only way of communicating the information to the parent scope is to use set(VAR_NAME value PARENT_SCOPE)
.
Using this command isn't well maintainable when using add_subdirectory
though, since you need to remember to use set(... PARENT_SCOPE)
in every subdirectory.
You could simply introduce a global cmake property of your own for this though.
#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)
Introduce the global property in the toplevel CMakeLists.txt
and you'll be able to add to the property and read the current value of the property from anywhere using the commands above.