tutorial target_link_libraries c++ cmake dynamic-linking

c++ - target_link_libraries - cmake.. command



CMake y orden de enlace dependiente de bibliotecas compartidas. (2)

Puede especificar la relación entre b agregando

target_link_libraries(b a)


De la docs :

Las dependencias de la biblioteca son transitivas por defecto. Cuando este objetivo está vinculado a otro objetivo, las bibliotecas vinculadas a este objetivo también aparecerán en la línea de enlace del otro objetivo.

Entonces, si especifica a como una dependencia de b de esta manera, ni siquiera necesita enumerar explícitamente a en cualquier objetivo que dependa de b , es decir, su otro comando puede ser simplemente:

target_link_libraries(dummy b)

aunque no haría ningún daño enlistar también.

Tengo algunos componentes pequeños que estoy creando como bibliotecas compartidas para mi aplicación principal. Vamos a usar un ejemplo de liba y libb . Cada uno está construido dentro de su propio subdirectorio de la siguiente manera:

add_library(liba SHARED a.cpp)

Luego, en la carpeta del proyecto raíz, necesito vincular mi aplicación principal a ambas.

include_directories(a) include_directories(b) add_executable(dummy dummy.cpp) target_link_libraries(dummy a b)

CMake funciona bien con esto, y mi aplicación compila pero no puede enlazar. El problema es que b hace referencia a. Si proporciono el orden de las bibliotecas al enlazar como

target_link_libraries(dummy b a)

El programa compila y enlaza muy bien.

Cuando este tipo de sistema comienza involucrando una interdependencia más compleja de las bibliotecas, comienza a ser imposible incluso si las dependencias son acíclicas. ¿Cómo manejo el paso de enlace aquí? ¿Hay algún truco para ordenar bibliotecas para enlazar en CMake?


Una solución fácil (especialmente para dependencias circulares) puede ser simplemente poner todas sus bibliotecas en una variable de lista, luego agregar esa lista dos veces (o más si es necesario), como:

set(LINK_LIBS "liba libb libc") target_link_libraries(app ${LINK_LIBS} ${LINK_LIBS})

(o simplemente escriba la lista dos veces después de la otra en la función target_link_libraries )

Esto me ha funcionado un par de veces, pero admito que puede haber algunos inconvenientes que no conozco (aparte de que parecen un poco pirateados).