Sto cercando di acquisire un elenco dei percorsi assoluti per tutte le librerie collegate a una destinazione specifica in CMake da utilizzare in una chiamata a add_custom_command
. Tuttavia, get_target_property(_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES
include solo le dipendenze dirette (ad esempio, tutto ciò che viene utilizzato in una chiamata target_link_libraries(${TARGET} ...)
).Elenco ricorsivo di LINK_LIBRARIES in CMake
Pertanto, se collego un altro target CMake, ad es. mylibrary
, l'elenco include mylibrary
, ma solo come nome e senza librerie collegate in modo transitorio. Poiché questo elenco può anche includere espressioni generatrici arbitrariamente complesse, controllare ciascun elemento se si tratta di un obiettivo e recuperare il suo codice LINK_LIBRARIES
in modo ricorsivo non è fattibile. Inoltre, l'obiettivo potrebbe essere specificato in un momento successivo nello CMakeLists.txt
e if(TARGET mylibrary)
verrà saltato.
Per INCLUDE_DIRECTORIES
e COMPILE_DEFINITIONS
questo è facilmente risolto, come anche se entrambi comportarsi in modo simile quando get_target_property
viene utilizzato (eccetto che obiettivi legati non sono ovviamente nella lista), un generatore di espressione della forma $<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>
produce l'elenco desiderato include ricorsivamente richiesto e definizioni. Tuttavia, $<TARGET_PROPERTY:${TARGET},LINK_LIBRARIES>
produce lo stesso elenco della variante get_target_property
.
Come posso recuperare l'elenco di percorsi assoluti desiderato?
Dimostrazione:
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)
uscita:
(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
@ usr1234567 si prega di leggere la domanda correttamente come già afferma i due approcci che ho provato e perché non funzionano. – Joe
Hai ragione, mi dispiace. Volevo vedere del codice ma non sarebbe stato d'aiuto. – usr1234567
Sì, potrei provare a fare un esempio minimale ma non mi è sembrato tutto così utile. – Joe