你没有提到你的 CMake 版本,所以我假设 3.8 或更好,这个解决方案已经过测试。
一种可能的解决方案是遍历项目中的所有子目录,然后将BUILDSYSTEM_TARGETS 应用于每个子目录。为了简单和可读性,我把它分成三个不同的宏。
首先,我们需要一种递归获取项目中所有子目录的方法。为此,我们可以使用file(GLOB_RECURSE ...) 并将LIST_DIRECTORIES 设置为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()
其次,我们需要一种方法来获取特定目录级别的所有目标。 DIRECTORY 带有一个可选参数,即您要查询的目录,这是它工作的关键:
#
# 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()
第三,我们需要另一个宏将所有这些联系在一起:
#
# 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()
最后,这里是你如何使用它:
get_all_targets(ALL_TARGETS ${CMAKE_CURRENT_LIST_DIR})
ALL_TARGETS 现在应该是一个列表,其中包含在调用者目录级别下创建的每个目标的名称。请注意,它不包括在当前CMakeLists.txt 中创建的任何目标。为此,您可以额外致电get_targets_by_directory(ALL_TARGETS ${CMAKE_CURRENT_LIST_DIR})。