Come faccio a dire a CMake di collegarsi a una libreria statica nella directory di origine?


96

Ho un piccolo progetto con un Makefile che sto cercando di convertire in CMake, principalmente solo per fare esperienza con CMake. Per gli scopi di questo esempio, il progetto contiene un file sorgente (C ++, anche se non credo che il linguaggio sia particolarmente rilevante) e un file di libreria statica che ho copiato altrove. Supponiamo per amor di discussione che il codice sorgente della libreria non sia disponibile; Ho solo il file .a e l'intestazione corrispondente.

Il mio Makefile fatto a mano contiene questa regola di costruzione:

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

che funziona bene. Come dico a CMake di riprodurlo? Non letteralmente questo esatto makefile, ovviamente, ma qualcosa che include un comando di collegamento equivalente. Ho provato i modi ovvi ma ingenui, come

add_executable(main main.cpp libbingitup.a)

o

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

così come varie cose con link_directories(.)o add_library(bingitup STATIC IMPORTED)ecc. ma finora niente che si traduca in un collegamento riuscito. Cosa dovrei fare?


Dettagli sulla versione: CMake 2.8.7 su Linux (Kubuntu 12.04) con GCC 4.6.3

Risposte:


121

CMake preferisce passare il percorso completo alle librerie di collegamento, quindi supponendo che libbingitup.a sia presente ${CMAKE_SOURCE_DIR}, le seguenti operazioni dovrebbero riuscire:

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

2
Fantastico, funziona, grazie! Sembra un po 'hacker dover inserire il percorso completo esplicitamente qui, ma immagino che sia solo il modo CMake ...
David Z

4
Sono d'accordo che sembra eccessivo qui, ma specificare esplicitamente il percorso completo paga i dividendi se hai più versioni diverse della stessa libreria installate.
Fraser

1
Fantastico, come al solito! Nel mio caso, ho risolto un problema di librerie che dipendevano da un'altra libreria dinamica costruita che dipendeva da una libreria statica: anche le librerie dipendenti stavano cercando di collegarsi a questa libreria statica.
Antonio

1
Come fa main a sapere delle directory include?
ManuelSchneid3r

3
Dovresti usare target_include_directorieso include_directories(il primo è il modo preferito in quanto è più specifico).
Fraser

31

Se non vuoi includere il percorso completo, puoi farlo

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

bingitup è lo stesso nome che daresti a un target se crei la libreria statica in un progetto CMake:

add_library(bingitup STATIC bingitup.cpp)

CMake aggiunge automaticamente il liball'inizio e .aalla fine su Linux e .liballa fine su Windows.

Se la libreria è esterna, potresti voler aggiungere il percorso alla libreria utilizzando

link_directories(/path/to/libraries/)

1
E se ci sono file .a e .so con lo stesso nome, come specifichi che vuoi collegare con .a o .so in questo caso?
George

1
@ George: non puoi. Se sono presenti entrambi i tipi, includi il nome completo del file a cui desideri collegarti.
Cris Luengo

21

L'ho trovato utile ...

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

Dal loro esempio:

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
E per INCLUDE_DIRECTORIES?
kyb

1
Funziona solo se la libreria fa parte della build cmake, ma per quelle straniere non funziona
eigenfield

la domanda dice "il progetto contiene un file sorgente (C ++, anche se non credo che il linguaggio sia particolarmente rilevante) e un file di libreria statica che ho copiato da qualche altra parte."
stu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.