I'm writing a CMakeLists.txt to generate files and compile the generated files. I create a function to add some file path strings to a global list variable.
My 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}\"")
The cmake output:
At last, the source_list is:"nothing"
Someone suggested that to use macro instead of function, but I do need use local variable, so I need to use the function instead of macro.
How can I correctly set the global variable source_list in the function test()? Can't cmake do it in a simple and normal way?
You need to use set
instead of list
to affect the variable in the parent scope.
So replace your list
command with:
set(source_list ${source_list} ${file_path} PARENT_SCOPE)
PARENT_SCOPE is only for parent, it won't work if you have other non-parent script that want to see it as well.
You need cache for the true "global-like" variable. In your case, use:
SET(source_list "${source_list}" CACHE INTERNAL "source_list")
Another approach is to use global properties. Once you set it:
set_property(GLOBAL PROPERTY source_list_property "${source_list}")
you can read it from everywhere:
get_property(source_list GLOBAL PROPERTY source_list_property)
I used in examples above the different names for property (source_list_property
) and for variable (source_list
). Maybe it is better to use the same name. But point is to use a property as global variables, and not about naming.
Such global properties aren't in cache.
Building upon Maxim Suslov's answer, the following code worked for a similar problem I faced:
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}")
Function add_source can be called from inside any sub-directory.