使用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()
参考