我正在尝试获取链接到 CMake 中特定目标的所有库的绝对路径列表,以便在调用中使用add_custom_command
。然而,get_target_property(_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES
只包括直接依赖项(即在target_link_libraries(${TARGET} ...)
call).
因此,如果我链接另一个 CMake 目标,例如mylibrary
,该列表将包括mylibrary
,但仅作为名称且不具有传递链接库。由于此列表还可以包含任意复杂的生成器表达式,因此检查每个项目是否是目标并检索其LINK_LIBRARIES
递归地是不可行的。此外,可以在稍后的时间点指定目标CMakeLists.txt
and if(TARGET mylibrary)
将被跳过。
For INCLUDE_DIRECTORIES
and COMPILE_DEFINITIONS
这很容易解决,因为尽管两者的行为相似get_target_property
使用(除了链接目标显然不在列表中),形式的生成器表达式$<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>
生成所需的递归所需包含和定义列表。然而,$<TARGET_PROPERTY:${TARGET},LINK_LIBRARIES>
产生与以下相同的列表get_target_property
变体。
如何检索所需的绝对路径列表?
示范:
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
file(WRITE a.cpp "void foo() {};\n")
file(WRITE b.cpp "int main(int, char**) { return 0; }\n")
find_package(Boost REQUIRED COMPONENTS filesystem system)
add_library(A STATIC a.cpp)
target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(A PUBLIC ${Boost_LIBRARIES})
# demonstrates (at configure time) that the LINK_LIBRARIES property can contain
# arbitrary generator expressions, making a recursive solution infeasible
get_target_property(A_LINK_LIBRARIES A LINK_LIBRARIES)
message(STATUS "A LINK_LIBARIES: ${A_LINK_LIBRARIES}")
add_executable(B b.cpp b_lists)
target_link_libraries(B PRIVATE A)
target_include_directories(B PRIVATE .)
get_target_property(B_INCLUDE_DIRECTORIES B INCLUDE_DIRECTORIES)
get_target_property(B_LINK_LIBRARIES B LINK_LIBRARIES)
# demonstrates (at compile time) that method 1 is not recursive while method 2 is (for INCLUDE_DIRECTORIES)
# demonstrates (at compile time) that the library list is never recursive
add_custom_command(
OUTPUT b_lists
COMMAND ${CMAKE_COMMAND} -E echo "B INCLUDE_DIRECTORIES 1: ${B_INCLUDE_DIRECTORIES}"
COMMAND ${CMAKE_COMMAND} -E echo "B INCLUDE_DIRECTORIES 2: $<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>"
COMMAND ${CMAKE_COMMAND} -E echo "B LINK_LIBRARIES 1: ${B_LINK_LIBRARIES}"
COMMAND ${CMAKE_COMMAND} -E echo "B LINK_LIBRARIES 2: $<TARGET_PROPERTY:B,LINK_LIBRARIES>"
DEPENDS A
)
set_source_files_properties(b_lists PROPERTIES SYMBOLIC TRUE)
Output:
(configure)
A LINK_LIBARIES: $<$<NOT:$<CONFIG:DEBUG>>:D:/libs/boost-1_55_0/lib/boost_filesystem-vc110-mt-1_55.lib>;$<$<CONFIG:DEBUG>:D:/libs/boost-1_55_0/lib/boost_filesystem-vc110-mt-gd-1_55.lib>;$<$<NOT:$<CONFIG:DEBUG>>:D:/libs/boost-1_55_0/lib/boost_system-vc110-mt-1_55.lib>;$<$<CONFIG:DEBUG>:D:/libs/boost-1_55_0/lib/boost_system-vc110-mt-gd-1_55.lib>
(build)
Generating b_lists
B INCLUDE_DIRECTORIES 1: D:/projects/cmakeminimal/.
B INCLUDE_DIRECTORIES 2: D:/projects/cmakeminimal/.;D:/libs/boost-1_55_0/include/boost-1_55
B LINK_LIBRARIES 1: A
B LINK_LIBRARIES 2: A