Вы не упомянули свою версию 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
принимает необязательный параметр, а именно каталог, который вы запрашиваете sh, что является ключом для этого:
#
# 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()
В-третьих, нам нужен еще один макрос для t ie всего этого вместе :
#
# 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})
.