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:
Eventuali duplicati di [CMake link alla libreria esterna] (http://stackoverflow.com/questions/8774593/cmake-link-to-external- biblioteca) – usr1234567