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_subdirectoryand every call of a cmakefunction()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 useset(VAR_NAME value PARENT_SCOPE).Using this command isn't well maintainable when using
add_subdirectorythough, since you need to remember to useset(... PARENT_SCOPE)in every subdirectory.You could simply introduce a global cmake property of your own for this though.
Introduce the global property in the toplevel
CMakeLists.txtand you'll be able to add to the property and read the current value of the property from anywhere using the commands above.