我想让一个特定目标依赖于我项目中所有其他添加的目标。换一种说法 - 我希望这个目标(比如lint)在所有库和应用程序构建完成后运行。
在指定的顶级CMakeLists.txt文件中是否有办法project获取使用添加CMakeLists.txt的目录中其他文件添加的所有目标的列表add_subdirectory?然后我可以使用add_dependencies来指定顺序。有一个BUILDSYSTEM_TARGETS属性,但它仅适用于目录级别。
如果有其他方法可以实现这一点,请告诉我。我使用 CMake 3.14。
为了将来参考,我最终编写了自己的函数而不是宏。但这个概念与@thomas_f 接受的答案相同。
这是代码:
# Collect all currently added targets in all subdirectories
#
# Parameters:
# - _result the list containing all found targets
# - _dir root directory to start looking from
function(get_all_targets _result _dir)
get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
foreach(_subdir IN LISTS _subdirs)
get_all_targets(${_result} "${_subdir}")
endforeach()
get_directory_property(_sub_targets DIRECTORY "${_dir}" BUILDSYSTEM_TARGETS)
set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
endfunction()
Run Code Online (Sandbox Code Playgroud)
你没有提到你的 CMake 版本,所以我会假设3.8或者更好,这个解决方案已经过测试。
一种可能的解决方案是遍历项目中的所有子目录,然后应用于BUILDSYSTEM_TARGETS每个子目录。为了简单和可读性,我将它分成三个不同的宏。
首先,我们需要一种递归获取项目中所有子目录的方法。为此,我们可以使用file(GLOB_RECURSE ...)with LIST_DIRECTORIESset 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()
Run Code Online (Sandbox Code Playgroud)
其次,我们需要一种方法来获取特定目录级别的所有目标。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()
Run Code Online (Sandbox Code Playgroud)
第三,我们需要另一个宏来将所有这些联系在一起:
#
# 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()
Run Code Online (Sandbox Code Playgroud)
最后,这里是您如何使用它:
get_all_targets(ALL_TARGETS ${CMAKE_CURRENT_LIST_DIR})
Run Code Online (Sandbox Code Playgroud)
ALL_TARGETS现在应该是一个列表,其中包含在调用者目录级别下创建的每个目标的名称。注意,它并没有包括在当前创建的任何目标CMakeLists.txt。为此,您可以额外调用get_targets_by_directory(ALL_TARGETS ${CMAKE_CURRENT_LIST_DIR}).
| 归档时间: |
|
| 查看次数: |
1191 次 |
| 最近记录: |