2015-07-21 6 views
8

Si dispone di un progetto di libreria abilitato per CMake. Devi usarlo in un'altra libreria o eseguibile. Come utilizzare CMake per trovare e collegare alla libreria? Si può avere le seguenti preferenze:Come utilizzare CMake per trovare e collegare a una libreria utilizzando install-export e find_package?

  • scrivere la minor quantità possibile di codice caldaia-piastra
  • disaccoppiare i dettagli interni della biblioteca collegata dal bersaglio consumare

Idealmente, l'uso del biblioteca dovrebbe assomigliare a questo:

add_executable(myexe ...) 
target_link_libraries(myexe mylib) 
+0

Eventuali duplicati di [CMake link alla libreria esterna] (http://stackoverflow.com/questions/8774593/cmake-link-to-external- biblioteca) – usr1234567

risposta

18

Lasciatemi mostrare una possibile soluzione in un esempio concreto:

Il myapp progetto

Abbiamo un obiettivo eseguibile myapp. Lo stiamo collegando con mylib, che è costruito nel suo albero di compilazione. Nel CMakeLists.txt di myapp troviamo e specifichiamo mylib come dipendenza di myexe:

find_package(mylib REQUIRED) 
... 
add_executable(myexe ...) 
target_link_libraries(myexe mylib) 

Vediamo come impostare mylib e la costruzione di myexe per fare questo lavoro.

Il progetto mylib

La struttura della directory di mylib:

mylib 
- CMakeLists.txt 
- mylib.c 
+ include 
    - mylib.h # single public header 

Nel CMakeLists.txt di mylib abbiamo bisogno di creare il target e specificare le sue file di origine:

add_library(mylib mylib.c include/mylib.h) 

Il pubblico l'intestazione mylib.h sarà inclusa come #include "mylib.h" sia da parte mylib ed i clienti di mylib:

  • mylib stesso e altri obiettivi costruiti nel progetto CMake mylib s'(ad esempio esami) hanno bisogno di trovare include/mylib.h dall'albero mylib fonte
  • clienti di mylib costruiti nella loro propri progetti (come myexe) hanno bisogno di trovare include/mylib.h nella sua posizione installata

CMake ci permette di specificare sia percorsi di inclusione per mylib: 012.

target_include_directories(mylib PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> 
    $<INSTALL_INTERFACE:include>) 

Stiamo utilizzando l'opzione PUBLIC qui poiché questa intestazione è necessaria per l'interfaccia pubblica di mylib. Utilizzare PRIVATE per includere i percorsi interni a mylib.

Il numero INSTALL_INTERFACE specifica un percorso relativo alla radice di installazione, ovvero CMAKE_INSTALL_PREFIX.Per installare effettivamente l'intestazione pubblica:

install(FILES include/mylib.h DESTINATION include) 

Abbiamo anche bisogno di installare la libreria stessa e il cosiddetto modulo di configurazione e file correlati. Il modulo di configurazione è il file che verrà utilizzato dal consumo di progetti, ad esempio myapp per trovare mylib e ottenere tutti i parametri necessari per il collegamento con esso. È simile ai file .pc di pkg-config .

Abbiamo bisogno di due comandi install correlati. Il primo:

install(TARGETS mylib 
    EXPORT mylib-targets 
    ARCHIVE DESTINATION lib 
    LIBRARY DESTINATION lib 
    RUNTIME DESTINATION bin) 

L'elenco delle destinazioni necessarie a coprire tutti gli standard di installazione posizioni delle librerie statiche, dll 's e so' s. Se sei sicuro che la tua libreria sarà costruita esclusivamente come lib statico, un singolo DESTINATION lib lo farebbe.

La parte interessante è l'opzione EXPORT. Assegna l'elenco degli obiettivi (al momento, è solo mylib) all'identificatore mylib-targets. Questo identificatore verrà usato nel comando successivo per generare e installare alcuni file speciali che rendono find_package(mylib) lavoro nei progetti che consumano:

install(EXPORT mylib-targets 
    FILE mylib-config.cmake 
    DESTINATION lib/cmake/mylib) 

Questo comando genera più file:

  • un file per ogni configurazione di generazione (Debug, Release, ecc.) Che descrive il file della libreria ei parametri dipendenti dalla configurazione
  • un file che descrive i parametri agnostici della configurazione e include anche tutti i file dipendenti dalla configurazione. Dal momento che questo file può essere utilizzato anche come un config-modulo sul proprio abbiamo semplicemente rinominarlo come mylib-config.cmake

I file verranno installati nella ${CMAKE_INSTALL_PREFIX}/lib/cmake/mylib che è uno dei tanti percorsi standard il comando find_package(mylib) cercherà mylib-config.cmake.

Costruire mylib

Abbiamo bisogno di specificare un percorso di installazione nella variabile CMAKE_INSTALL_PREFIX:

mkdir build 
cd build 
cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 

e costruire e installare la libreria:

cmake --build . --target install 

costruzione myexe

myexe ha bisogno di sapere dove cercare mylib. La variabile CMAKE_PREFIX_PATH può essere un elenco di percorsi. Abbiamo bisogno di specificare il precedente percorso di installazione:

mkdir build 
cd build 
cmake -DCMAKE_PREFIX_PATH=$PWD/../out ../mylib 
cmake --build . 

Una nota sulla costruzione di configurazioni multiple

Di solito abbiamo bisogno di costruire configurazioni multiple (Debug, Release). Un problema critico è specificare nomi di file dipendenti dalla configurazione o percorsi di installazione.Ad esempio, è possibile impostare il valore predefinito della proprietà DEBUG_POSTFIX per il progetto di libreria:

set(CMAKE_DEBUG_POSTFIX d) 

La versione di debug del file di libreria mylib verrà denominato libmylibd.lib (o mylibd.lib su Windows). I file EXPORT generati conterranno i nomi file modificati.

Se stai usando makefile in stile CMake generatori è possibile controllare la configurazione di generazione impostando la variabile CMAKE_BUILD_TYPE:

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 
cmake --build . --target install 

potrebbe essere necessario directory di compilazione separate per ogni configurazione oppure è possibile riutilizzare la stessa costruire dir. In questo caso, andare sul sicuro è meglio esplicitamente pulita prima di build:

cmake --build . --target install --clean-first 

Se stai usando un generatore di IDE MultiConfig, come Xcode o Visual Studio, è necessario specificare la configurazione in tempo di costruzione:

cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 
cmake --build . --target install --config Release 

Riferimenti

è possibile clonare e costruire this repository che contiene i progetti mylib e myexe (testato su Windows e Linux).

Verificare il CMake documentation. I più importanti comandi correlati sono:

e due deta articoli ILED: