Come utilizzo CMake per creare la mia base di codici per scopi e risoluzioni diversi?

1

Sto lavorando su un codebase C ++ indirizzato a più piattaforme e ci siamo appena trasferiti a CMake come nostro sistema di build.

In precedenza il nostro buildsystem era un bel caso ad-hoc; ottenere il nostro codice sotto un singolo sistema di build comune è stato un vero passo in avanti.

Il prossimo punto dolente che ho riscontrato, però, è che mi piacerebbe essere in grado di costruire il nostro progetto in una varietà di ambiti. Ad esempio:

  • A volte voglio creare un modulo particolare, oltre ai suoi test. O una suite di moduli, oltre ai loro test.
  • A volte voglio creare uno dei nostri pacchetti di produzione (che avrà prodotti di sviluppo organizzati in un modo completamente diverso rispetto a quelli di testing durante lo sviluppo).
  • A volte voglio creare la base di codici whooole, inclusi strumenti e utilità secondarie.

... e, naturalmente, preferirei evitare di costruire assolutamente tutto come opzione "predefinita" che è difficile da cambiare. Ma questa sembra essere l'opzione predefinita di CMake: tutto è incluso nell'albero dei sorgenti, a meno che non specifichi i singoli obiettivi per nome.

Due opzioni che sembrano promettenti, ma mi sento insoddisfatta, sono:

1. Utilizza le funzioni INSTALL e COMPONENT di CMake. Sembra che mi dia quello che voglio: diverse configurazioni di installazione per lo stesso codice base. Tuttavia,

  • Per quanto ne so, INSTALL dipende da tutti gli altri target , quindi per la maggior parte delle configurazioni vorrei costruisci lotti di prodotti di cui non ho bisogno.
  • COMPONENT è un parametro per CMake stesso; Avrei bisogno di directory di compilazione completamente indipendenti per creare diversi componenti di installazione. Se passo da un componente all'altro, ho bisogno di ricostruire tutto .

2. Crea bersagli personalizzati che rappresentano i miei diversi ambiti / componenti, descrivendo quali obiettivi ciascun "componente" dipende da.

  • Questo sembra implicare rinunciare completamente alla funzionalità INSTALL . E se qualcuno dei miei casi d'uso ha bisogno che i prodotti di costruzione siano impostati in un particolare layout, o quant'altro INSTALL -like (molti di loro lo fanno), avrei bisogno di ricrearlo manualmente come parte di ciascuna di queste abitudini obiettivi. Questo sembra terribilmente ingombrante.

C'è un modo migliore per definire diversi "tipi" di build? (Oppure, mi manca un modo migliore di gestirlo?)

    
posta Standback 25.07.2016 - 09:40
fonte

1 risposta

1

Crea semplicemente più destinazioni, una destinazione per componente:

# Setup three "components"
add_library(first source1.cpp source2.cpp)
add_library(second source3.cpp source4.cpp)
add_executable(third source5.cpp source6.cpp)

# 'third' depends on the other libraries
add_dependency(third first second)

In questo esempio potresti chiamare make first per creare solo la prima libreria, ad es. first.dll o first.so . Rilasciando make third devi creare first e second , quindi third e collegare tutto.

Ovviamente potresti creare, mixare e abbinare altri tipi di target, come eseguibili, librerie statiche, test, ecc.

Ad esempio, per aggiungere un codice di prova (usando CTest) sopra:

enable_testing()
add_test(test-first some/command/to/run)
add_dependency(test-first first)

Ora ogni volta che eseguirai make test-first , prima creerebbe first e poi eseguirà il test test-first .

Per quanto riguarda la confezione e le cose personalizzate, probabilmente utilizzerei solo add_custom_target() per questo.

    
risposta data 25.07.2016 - 10:02
fonte

Leggi altre domande sui tag