You did not mention your CMake version, so I will assume 3.8
or better, for which this solution has been tested.
One possible solution is to iterate through all sub-directories in your project, and then apply BUILDSYSTEM_TARGETS
to each of them. For the sake of simplicity and readability, I have split this up into three different macros.
First, we need a way of recursively obtaining all sub-directories in the project. For this, we can use file(GLOB_RECURSE ...)
with LIST_DIRECTORIES
set to ON
:
#
# Get all directories below the specified root directory.
# _result : The variable in which to store the resulting directory list
# _root : The root directory, from which to start.
#
macro(get_directories _result _root)
file(GLOB_RECURSE dirs RELATIVE ${_root} LIST_DIRECTORIES ON ${_root}/*)
foreach(dir ${dirs})
if(IS_DIRECTORY ${dir})
list(APPEND ${_result} ${dir})
endif()
endforeach()
endmacro()
Secondly, we need a way to obtain all targets at a particular directory level. DIRECTORY
takes an optional parameter, namely the directory you wish to query, which is key for this to work:
#
# Get all targets defined at the specified directory (level).
# _result : The variable in which to store the resulting list of targets.
# _dir : The directory to query for targets.
#
macro(get_targets_by_directory _result _dir)
get_property(_target DIRECTORY ${_dir} PROPERTY BUILDSYSTEM_TARGETS)
set(_result ${_target})
endmacro()
Thirdly, we need another macro to tie all this together:
#
# Get all targets defined below the specified root directory.
# _result : The variable in which to store the resulting list of targets.
# _root_dir : The root project root directory
#
macro(get_all_targets _result _root_dir)
get_directories(_all_directories ${_root_dir})
foreach(_dir ${_all_directories})
get_targets_by_directory(_target ${_dir})
if(_target)
list(APPEND ${_result} ${_target})
endif()
endforeach()
endmacro()
Finally, here is how you can use it:
get_all_targets(ALL_TARGETS ${CMAKE_CURRENT_LIST_DIR})
ALL_TARGETS
should now be a list holding the names of every target created below the caller's directory level. Note that it does not include any targets created in the current CMakeLists.txt
. For that, you can make an extra call to get_targets_by_directory(ALL_TARGETS ${CMAKE_CURRENT_LIST_DIR})
.