使用CMake,我如何获得进入可执行目标的所有源文件的列表,包括此可执行文件所依赖的所有目标中的所有源?
我们在代码库中有一个模式,其中初始化调用者是由构建系统根据源树中的文件名和路径生成的.因此,我需要可执行目标所依赖的所有源文件的完整路径(或相对于源根目录).
这是我的一段代码,用于获取一个目标的链接依赖项:
function(target_link_libraries _target) set(_mode "PUBLIC") foreach(_arg IN LISTS ARGN) if (_arg MATCHES "INTERFACE|PUBLIC|PRIVATE|LINK_PRIVATE|LINK_PUBLIC|LINK_INTERFACE_LIBRARIES") set(_mode "${_arg}") else() if (NOT _arg MATCHES "debug|optimized|general") set_property(GLOBAL APPEND PROPERTY GlobalTargetDepends${_target} ${_arg}) endif() endif() endforeach() _target_link_libraries(${_target} ${ARGN}) endfunction() function(get_link_dependencies _target _listvar) set(_worklist ${${_listvar}}) if (TARGET ${_target}) list(APPEND _worklist ${_target}) get_property(_dependencies GLOBAL PROPERTY GlobalTargetDepends${_target}) foreach(_dependency IN LISTS _dependencies) if (NOT _dependency IN_LIST _worklist) get_link_dependencies(${_dependency} _worklist) endif() endforeach() set(${_listvar} "${_worklist}" PARENT_SCOPE) endif() endfunction()
对于较旧的CMake版本(3.4之前的版本),您需要使用列表(FIND …)调用替换IN_LIST检查:
[...] list(FIND _worklist ${_dependency} _idx) if (${_idx} EQUAL -1) get_link_dependencies(${_dependency} _worklist) endif() [...]
这是我用过的测试代码:
cmake_minimum_required(VERSION 3.4) project(GetSources) cmake_policy(SET CMP0057 NEW) [... include functions posted above ...] file(WRITE a.cc "") add_library(A STATIC a.cc) file(WRITE b.cc "") add_library(B STATIC b.cc) file(WRITE main.cc "int main() { return 0; }") add_executable(${PROJECT_NAME} main.cc) target_link_libraries(B A) target_link_libraries(${PROJECT_NAME} B) get_link_dependencies(${PROJECT_NAME} _deps) foreach(_dep IN LISTS _deps) get_target_property(_srcs ${_dep} SOURCES) get_target_property(_src_dir ${_dep} SOURCE_DIR) foreach(_src IN LISTS _srcs) message("${_src_dir}/${_src}") endforeach() endforeach()
参考