¿Cómo le digo a CMake que se vincule en una biblioteca estática en el directorio de origen?


96

Tengo un pequeño proyecto con un Makefile que estoy tratando de convertir a CMake, principalmente para obtener experiencia con CMake. Para los propósitos de este ejemplo, el proyecto contiene un archivo fuente (C ++, aunque no creo que el lenguaje sea particularmente relevante) y un archivo de biblioteca estática que he copiado de otra parte. Supongamos por el bien del argumento que el código fuente de la biblioteca no está disponible; Solo tengo el archivo .a y el encabezado correspondiente.

Mi Makefile hecho a mano contiene esta regla de compilación:

main: main.o libbingitup.a
    g++ -o main main.o libbingitup.a

que funciona bien. ¿Cómo le digo a CMake que reproduzca esto? No literalmente este archivo MAKE exacto, por supuesto, sino algo que incluye un comando de vinculación equivalente. He probado las formas obvias pero ingenuas, como

add_executable(main main.cpp libbingitup.a)

o

add_executable(main main.cpp)
target_link_libraries(main libbingitup.a)

así como varias cosas con link_directories(.)o add_library(bingitup STATIC IMPORTED)etc. pero nada hasta ahora que resulte en una vinculación exitosa. ¿Qué debería estar haciendo?


Detalles de la versión: CMake 2.8.7 en Linux (Kubuntu 12.04) con GCC 4.6.3

Respuestas:


121

CMake favorece pasar la ruta completa para vincular bibliotecas, por lo que suponiendo que libbingitup.a esté adentro ${CMAKE_SOURCE_DIR}, hacer lo siguiente debería tener éxito:

add_executable(main main.cpp)
target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)

2
Genial, eso funciona, ¡gracias! Parece un poco complicado tener que incluir la ruta completa explícitamente aquí, pero supongo que esa es la forma de CMake ...
David Z

4
Estoy de acuerdo en que parece exagerado aquí, pero especificar explícitamente la ruta completa paga dividendos si tiene instaladas varias versiones diferentes de la misma biblioteca.
Fraser

1
¡Increíble, como siempre! En mi caso, resolvió un problema de bibliotecas que dependían de otra biblioteca dinámica construida que dependía de una biblioteca estática: las bibliotecas dependientes también intentaban vincularse a esta biblioteca estática.
Antonio

1
¿Cómo sabe Main sobre los directorios de inclusión?
ManuelSchneid3r

3
Necesitaría usar target_include_directorieso include_directories(la primera es la forma preferida ya que es más específica).
Fraser

31

Si no desea incluir la ruta completa, puede hacer

add_executable(main main.cpp)
target_link_libraries(main bingitup)

bingitup es el mismo nombre que le daría a un objetivo si crea la biblioteca estática en un proyecto de CMake:

add_library(bingitup STATIC bingitup.cpp)

CMake agrega automáticamente el libal frente y .aal final en Linux, y .libal final en Windows.

Si la biblioteca es externa, es posible que desee agregar la ruta a la biblioteca usando

link_directories(/path/to/libraries/)

1
Y si hay archivos .ay .so con el mismo nombre, ¿cómo especifica que desea vincular con el .a o el .so en este caso?
George

1
@George: No puedes. Si tiene ambos tipos presentes, incluya el nombre completo del archivo que desea vincular.
Cris Luengo

21

Encontré esto útil ...

http://www.cmake.org/pipermail/cmake/2011-June/045222.html

De su ejemplo:

ADD_LIBRARY(boost_unit_test_framework STATIC IMPORTED)
SET_TARGET_PROPERTIES(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a)
TARGET_LINK_LIBRARIES(mytarget A boost_unit_test_framework C)

3
¿Qué pasa con INCLUDE_DIRECTORIES?
kyb

1
Esto solo funciona si la biblioteca es parte de la compilación de cmake, pero las externas, esto no funciona
eigenfield

la pregunta dice "el proyecto contiene un archivo fuente (C ++, aunque no creo que el lenguaje sea particularmente relevante) y un archivo de biblioteca estática que he copiado de otro lugar".
Stu
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.