Wish: add_subdirectory without creating a new scope
As mentioned in the documentation of the set command, each directory added with add_subdirectory creates a new scope.
The new child scope inherits a copy of the variables defined in its parent scope, and changes to those variables are only visible in the child scope unless the PARENT_SCOPE option is used.
However, I think it's a bit confusing that changes made using the PARENT_SCOPE
option ONLY affect the parent scope (and not the copy of the same variable in the child scope).
Let's say a I have a variable LIST_OF_FILES
that contains a.cpp
and b.cpp
, then from a child CMake file I added with add_subdirectory
I do:
set(LIST_OF_FILES ${LIST_OF_FILES} first.cpp PARENT_SCOPE)
set(LIST_OF_FILES ${LIST_OF_FILES} second.cpp PARENT_SCOPE)
set(LIST_OF_FILES ${LIST_OF_FILES} third.cpp PARENT_SCOPE)
Counter-intuitively, what I actually get in the original scope is a.cpp b.cpp third.cpp
, because the LIST_OF_FILES
variable in the child scope was never updated between one set
call and the next.
A workaround is to keep the changes in the child scope and only once at the end propagate them to the parent scope:
set(LIST_OF_FILES ${LIST_OF_FILES} first.cpp)
set(LIST_OF_FILES ${LIST_OF_FILES} second.cpp)
set(LIST_OF_FILES ${LIST_OF_FILES} third.cpp)
set(LIST_OF_FILES ${LIST_OF_FILES} PARENT_SCOPE)
IMHO it would make more sense that PARENT_SCOPE
modified both the parent and child scopes, but I assume this is a breaking change that might not be possible to make.
So, an alternative solution (and the one I'm proposing here) would be to simplify this use case and add a way to add directories without creating a child scope, so we don't have to think about scopes in the first place. This would be a new option in add_subdirectory
, so it would not be a breaking change.