我正在尝试获取链接到CMake中特定目标的所有库的绝对路径列表,以便在调用em
时使用。但是,.main {
width:378px;
height:250px;
}
仅包含直接依赖项(即table.setIntercellSpacing(new Dimension(0, 0))
调用中使用的任何内容)。
因此,如果我链接另一个CMake目标,例如add_custom_command
,列表将包含get_target_property(_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES
,但仅作为名称,不包含可传递链接的库。由于此列表还可以包含任意复杂的生成器表达式,因此检查每个项目是否为目标并以递归方式检索其target_link_libraries(${TARGET} ...)
是不可行的。此外,可以在mylibrary
稍后指定目标,并跳过mylibrary
。
对于LINK_LIBRARIES
和CMakeLists.txt
,这很容易解决,因为虽然使用if(TARGET mylibrary)
时两者的行为相似(除了链接目标显然不在列表中),但生成器表达式为形式INCLUDE_DIRECTORIES
生成所需的递归必需包含和定义列表。但是,COMPILE_DEFINITIONS
会生成与get_target_property
变体相同的列表。
如何检索所需的绝对路径列表?
演示:
$<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>
输出:
$<TARGET_PROPERTY:${TARGET},LINK_LIBRARIES>
答案 0 :(得分:7)
你的愿望已经存在了一段时间,而且 - 据我所知 - 尚未(至于CMake 3.3.2)嵌入clinic.menu.item_set.all()
本身(见0012435: Possibility to get all link libraries for a target?)。
我有一些希望,因为这张票列出了一些可能的替代方法。但是在我针对您的示例CMake
项目测试了这些后,我会说它们不是真正的解决方案:
export_library_dependencies()
- 已弃用
注意:因为这仅适用于Lib-To-Lib依赖项,所以我对此测试将CMake
更改为add_executable()
调用
add_library()
会给出例如。
cmake_policy(SET CMP0033 OLD)
export_library_dependencies(LibToLibLinkDependencies.cmake)
include("${CMAKE_CURRENT_BINARY_DIR}/LibToLibLinkDependencies.cmake")
message("A_LIB_DEPENDS: ${A_LIB_DEPENDS}")
message("B_LIB_DEPENDS: ${B_LIB_DEPENDS}")
另见policy CMP0033 "The export_library_dependencies() command should not be called"
A_LIB_DEPENDS: optimized;../libboost_filesystem-vc110-mt-1_53.lib;debug;../libboost_filesystem-vc110-mt-gd-1_53.lib;...
B_LIB_DEPENDS: general;A;
但这会将生成器表达式保留在输出中,您需要将所有依赖目标添加到列表中,所以没有好处。
我从how to use the cmake functions get_prerequisites and get_filename_component for target dependency installation?获取了代码,但它显示了 - 如模块文档中所述 - 它只列出共享库。
cmake_policy(SET CMP0024 OLD)
export(
TARGETS A B
FILE Test.cmake
NAMESPACE Imp_
)
include("${CMAKE_CURRENT_BINARY_DIR}/Test.cmake")
<强> ListSharedLibDependencies.cmake 强>
add_custom_command(
OUTPUT b_lists
APPEND
COMMAND ${CMAKE_COMMAND} -D MY_BINARY_LOCATION="$<TARGET_FILE:B>" -P "${CMAKE_CURRENT_LIST_DIR}/ListSharedLibDependencies.cmake"
)
将在我的Windows机器上输出:
include(GetPrerequisites)
get_prerequisites(${MY_BINARY_LOCATION} DEPENDENCIES 0 0 "" "")
foreach(DEPENDENCY_FILE ${DEPENDENCIES})
gp_resolve_item("${MY_BINARY_LOCATION}" "${DEPENDENCY_FILE}" "" "" resolved_file)
message("resolved_file='${resolved_file}'")
endforeach()
<强>参考强>
答案 1 :(得分:4)
可以递归遍历LINK_LIBRARY
属性。
这是get_link_libraries()
这样做,但它不处理所有情况(例如,库不是目标,而不是导入的库)。
function(get_link_libraries OUTPUT_LIST TARGET)
get_target_property(IMPORTED ${TARGET} IMPORTED)
list(APPEND VISITED_TARGETS ${TARGET})
if (IMPORTED)
get_target_property(LIBS ${TARGET} INTERFACE_LINK_LIBRARIES)
else()
get_target_property(LIBS ${TARGET} LINK_LIBRARIES)
endif()
set(LIB_FILES "")
foreach(LIB ${LIBS})
if (TARGET ${LIB})
list(FIND VISITED_TARGETS ${LIB} VISITED)
if (${VISITED} EQUAL -1)
get_target_property(LIB_FILE ${LIB} LOCATION)
get_link_libraries(LINK_LIB_FILES ${LIB})
list(APPEND LIB_FILES ${LIB_FILE} ${LINK_LIB_FILES})
endif()
endif()
endforeach()
set(VISITED_TARGETS ${VISITED_TARGETS} PARENT_SCOPE)
set(${OUTPUT_LIST} ${LIB_FILES} PARENT_SCOPE)
endfunction()