I’m trying to write a CMake function that takes a list as an argument, and that adds items to the list, and then returns so that the caller can use the modified list.
It sounds simple but I can’t get it to work. Here’s my best effort so far:
function(appendToList THE_LIST)
message("On entering appendToList, THE_LIST = ${THE_LIST}")
list(APPEND THE_LIST "item2")
list(APPEND THE_LIST "item3")
set(${THE_LIST} "${${THE_LIST}}" PARENT_SCOPE)
endfunction()
set(MY_LIST "item1")
appendToList(MY_LIST)
list(LENGTH MY_LIST nList)
message("On return from appendToList, the length of MY_LIST is ${nList}:")
foreach(item IN LISTS MY_LIST)
message("- ${item}")
endforeach()
I’d expect the output to be:
On entering appendToList, THE_LIST = item1
On return from appendToList, the length of MY_LIST is 3:
- item1
- item2
- item3
…but what I actually get is:
On entering appendToList, THE_LIST = MY_LIST
On return from appendToList, the length of MY_LIST is 3:
- item2
- item3
-
In my ‘real application’ (not the simple case cooked up for this question), I was having a second issue which led to an extra stray empty entry being added to the returned list.
The problem turned out to be that I was using the same variable name for both the list itself in the parent scope, and the argument of the function.
So, in the example above, using THE_LIST as the name of the function argument, whereas MY_LIST is the name of the list in the parent scope, everything works as expected.
But suppose I now change the function so that the argument is called MY_LIST instead:
function(appendToList MY_LIST)
message("On entering appendToList, THE_LIST = ${${MY_LIST}}")
list(APPEND ${MY_LIST} "item2")
list(APPEND ${MY_LIST} "item3")
set(${MY_LIST} "${${MY_LIST}}" PARENT_SCOPE)
endfunction()
set(MY_LIST "item1")
appendToList(MY_LIST)
list(LENGTH MY_LIST nList)
message("On return from appendToList, the length of MY_LIST is ${nList}:")
foreach(item IN LISTS MY_LIST)
message("- ${item}")
endforeach()
Then things go horribly wrong:
On entering appendToList, THE_LIST = MY_LIST
On return from appendToList, the length of MY_LIST is 4:
- item2
- item2
- item3
-
So it turns out that it’s very important to ensure that functions are not invoked using variables which have the same name as their parameters. I don’t recall seeing this documented anywhere.