CMake con le sottodirectory

Sto cercando di impostare il mio progetto per compilare correttamente utilizzando CMake.

Mio directory assomiglia a questo:

root
 |- bin
 |   |- //Where I want to build CMake from - using 'cmake ..'
 |- build
 |   |-
 |- include
 |   |- database
 |   |    |- database.h
 |- src
     |- database
     |    |- database.cpp
     |- main
          |- main.cpp

Mio sub-directories sarà sicuramente crescere il mio progetto cresce e pensato CMake sarebbe probabilmente una buona idea per imparare. Al momento posso solo ottenere CMake per lavorare senza la sotto-cartelle all’interno della mia src/. Tuttavia, mi aspetto questo progetto a crescere in molte sotto-directory.

Avrei bisogno di più CMakeLists.txt all’interno di ogni directory .i file cpp? Può qualcuno mi punto nella giusta direzione?

Grazie!

  • Penso CMakeLists.txt è solo uno e nella directory principale (P. S.) io non sono un esperto di cmake
  • Ho visto alcuni esempi di qui e alcune persone sono state suggerendo di più CMakeLists.txt però avevano un problema molto specifico e non so se è questa la soluzione al mio problema in particolare.
  • Hai preso uno sguardo al doc? cmake.org/examples
InformationsquelleAutor Van | 2017-03-12

 

2 Replies
  1. 11

    Il progetto non sembra aver bisogno di più CMakeLists.txt. Lo scopo di avere più CMakeLists.txt più volte è multi-fold, ma non mi sembra per adattarsi nel vostro progetto. Per esempio, il vantaggio sarebbe di organizzazione gerarchica, in modo che è possibile separare i diversi unità essere costruiti separatamente, e legata alla fine.

    Esempio

    Considerare la situazione se si dispone di un’altra directory principale denominata tests. La directory contiene test di unità che si desidera che il developer di scegliere se compilare o meno. In questo caso, mettete un CMakeLists.txt in tests, e si attiva questa primaria CMakeLists.txt con un add_subdirectory(test) così:

    if(testing_enabled)
        add_subdirectory(tests)
    endif()

    In tests, ci sarebbe un altro CMakeLists.txt. In questo modo, è possibile separare le preoccupazioni. Lo sviluppo di unità di test è indipendente dallo sviluppo del progetto, e anche il processo di generazione separata.

    Un altro esempio

    Considerare la situazione se si dispone di due biblioteche in cui l’utente può scegliere. In questo caso, siete in root due directory, lib1 e lib2. Ora si può fare qualcosa di simile primaria CMakeLists.txt:

    if(IWantLib1)
        add_subdirectory(lib1)
    else()
        add_subdirectory(lib2)
    endif()

    E sia lib1 e lib2 directory contengono CMakeLists.txt.

  2. 18

    Farà riferimento al questo articolo per una discussione approfondita dei due approcci principali, ma ci sono un paio di modi si potrebbe strutturare un progetto come questo.

    • Uno CMakeLists.txt file di livello superiore, che elenca tutti i file di origine in tutte le diverse sottodirectory. In genere si vede solo questa per progetti molto semplici.
    • Uno CMakeLists.txt file in ogni cartella, ogni uno ha portato dal suo genitore utilizzando add_subdirectory(). Questo approccio è molto comune.
    • Uno CMakeLists.txt file di alto livello, ogni sottodirectory di avere un file che elenca i propri file di origine e obiettivi. Il livello superiore CMakeLists.txt file porta nella sottodirectory file con include(). Meno comune, ma può avere vantaggi rispetto agli altri due.

    Ognuno ha i suoi pro e contro. Avendo un solo livello superiore CMakeLists.txt file dovrebbe essere raccomandato solo se ci sono stati molto pochi i file e le sottodirectory. Una volta che il progetto cresce, mantenendo tutto il livello superiore può diventare troppo e fare la risultante CMakeLists.txt file più difficile da seguire. Essa ha anche lo svantaggio che la modifica di un file, l’aggiunta o la rimozione non è limitato a una particolare directory. Questo può non sembrare un grande affare, ma se più persone stanno lavorando su un progetto e volete vedere facilmente quali parte di un progetto di qualcun altro modifiche interessano (ad esempio, in una storia di git), è più difficile. Questo è particolarmente vero se si sia aggiungere/rimuovere un file, in tal modo sia cambiare il livello superiore CMakeLists.txt file e avere la possibilità di un conflitto.

    Una volta che il progetto diventa banale dimensioni, la maggior parte sceglie di aggiungere un CMakeLists.txt file in ogni sottodirectory e utilizzare add_subdirectory() per portare tutti insieme. @TheQuantumPhysicist risposta dà un buon esempio di come questo può essere utile, quindi non mi ripeto più di quei dettagli qui. Questa struttura vi offre la possibilità di attivare/disattivare intere sezioni di costruire albero con facilità, ma la cosa più importante è che dà a ogni sottodirectory proprie scope di una variabile. Questo può essere importante se si desidera impostare le variabili, etc. in una parte dell’albero dei sorgenti, ma non hanno tali modifiche visibili in un’altra parte (si pensi flag di compilazione che solo si desidera applicare per una sezione di una complessa struttura di directory).

    La terza opzione di un livello superiore CMakeLists.txt file con ogni sottodirectory fornire un file portati da include() è meno comune, ma ci sono similitudini all’utilizzo di una CMakeLists.txt file in ogni sottodirectory. Sia localizzare i dettagli su file in una directory su un CMakeLists.txt o di altri aventi lo stesso nome del file appena in quella directory. Cambia, quindi, diventa più facile per unire e per capire in controllo di versione storici, ecc. Una cosa che questo terzo approccio permette che il secondo non lo è per uso target_link_libraries() un po ‘ più liberamente quando si utilizza target_sources() per specificare il file di origine in ogni sottodirectory. Articolo linkato all’inizio di questa risposta va in dettaglio su perché target_sources() può essere vantaggioso ed è al centro di questo terzo metodo può essere desiderabile per molti progetti.

    Infine, vi suggerisco non prendere l’abitudine di mettere il vostro costruire all’albero albero dei sorgenti. Piuttosto, creare, costruire il vostro albero(s), come fratelli di origine albero. Obiettivo di mantenere il vostro albero sorgente incontaminata da costruire. Tutto ciò che serve è avere qualcuno creare una directory nella struttura di origine con lo stesso nome, come tutto quello che hai utilizzato per la costruzione dell’albero che le cose vanno male (ho visto più di una volta!). Si potrebbe anche voler impostare più alberi per costruire una struttura di origine, ad esempio una per una build di Debug e l’altro come una build di Rilascio, in modo da avere questi fuori l’albero dei sorgenti aiuta anche a mantenere la struttura di origine meno affollato.

    • Ottimi consigli, vi ringrazio molto. Sul tuo ultimo punto, ho fatto un errore di battitura. Volevo dire che commentare la linea di costruzione.. io non costruire dalla directory bin. Immagino che la directory di compilazione è dove voglio richiamare CMake?
    • Sì, ho già pensato che significava che era in esecuzione CMake nel build directory piuttosto che bin. Il solito modo è quello di eseguire CMake dalla directory di compilazione. È possibile eseguire CMake ovunque e comunque utilizzare una directory specifica come la directory di compilazione utilizzando documenti -B opzione, ma non mi consiglia di farlo, a meno che ci sia una buona ragione.

Lascia un commento