C ++ Build Systems - Cosa usare? [chiuso]


136

Sto cercando di iniziare un nuovo progetto in C ++ - solo ai miei tempi inizialmente - e sto studiando i sistemi di build disponibili. Sembrerebbe che la risposta sia "Molti, e sono tutti orribili".

Le caratteristiche di cui ho specificamente bisogno per questo sono:

  1. Supporto per C ++ 11
  2. Cross platform (Linux come obiettivo principale, ma in grado di basarsi anche su Windows)
  3. Supporto per test unitari decenti
  4. Supporto per più moduli per la separazione del codice
  5. Supporto per la generazione di codice (utilizzando asn1c o protobuf - non ancora sicuro al 100%)
  6. Facile da mantenere

Ora, so di poter fare 1-4 di quelli che usano CMake e Autotools abbastanza facilmente. Probabilmente anche con SCons e Waf e anche gli altri. Il problema è che non ho mai capito come fare correttamente la generazione del codice usando loro - ovvero i file di origine che non esistono fino alla prima esecuzione del processo di compilazione, quindi i file di origine che il sistema di compilazione deve essere in grado di convertire in codice eseguibile ma in realtà non lo sa fino a quando non inizia la compilazione ... (ASN1C in particolare genera dozzine di file di intestazione e sorgente che devono essere in grado di lavorare insieme, e il set effettivo di file generato dipende dal contenuto del tuo file asn) anche il fatto che nessuno di questi è particolarmente facile da mantenere: CMake e Autotools hanno il loro enorme set di script che devi gestire affinché funzionino,

Quindi - quali sistemi di build sono consigliati per qualcosa del genere? O sarò bloccato con make files e script di shell per ora?


11
"Sembrerebbe che la risposta sia" Molti, e sono tutti orribili "" è anche la mia impressione (con l'aggiunta di "orribile dal mio punto di vista"; non mi piace generalizzare troppo con termini come questi ). In realtà ho creato il mio proprio per quello stesso motivo, e ha funzionato meglio del previsto poiché fa quello che voglio e come ho sempre voluto che le cose funzionassero. Per qualcosa che richiede un po 'meno tempo, probabilmente dovrai passare attraverso gli strumenti esistenti e sceglierne uno che ti dà meno mal di testa rispetto agli altri.
Christian Stieber,

4
Prova tup .
Kerrek SB,


8
Che tipo di supporto C ++ 11 ti aspetti da un sistema di compilazione? Questo è qualcosa che ottieni dal compilatore, il sistema di compilazione non analizza o nemmeno legge i file sorgente effettivi, li passa solo a chiunque ne abbia bisogno, no?
Baruch,

5
Vero, ma rendere facile dire al compilatore di usare il supporto C ++ 11 sarebbe buono. g ++ ha bisogno di un flag, clang un set diverso, a quanto pare msvc non ne ha bisogno e così via. Inoltre, il supporto per rilevare quali funzionalità di c ++ 11 sono disponibili sarebbe utile in quanto differisce anche tra i compilatori ...
Graham

Risposte:


117

+1 per "Molti e sono orribili".

Ma il "più ricco" e il "più scalabile" è probabilmente CMake , che è un generatore di Makefile (genera anche MSVC ++ *.proj/ *.sln) nativo . Sintassi strana, ma una volta appreso, può consentire di generare correttamente build per piattaforme diverse. Se avessi "iniziato da zero", probabilmente userei CMake. Dovrebbe gestire il tuo elenco, anche se la tua "generazione di codice" potrebbe assumere "una vita propria" oltre il sistema di generazione a seconda di ciò che vuoi fare. (Vedi sotto.)

Per progetti semplici, il generatore QMake è ok (non è necessario utilizzare le librerie Qt per utilizzare QMake). Ma non stai descrivendo "semplice" - la generazione di codice e "fasi extra" significa che probabilmente vuoi CMakequalcosa con un'API ricca per le tue estensioni, come Scons(o Waf).

Usiamo Scons al lavoro. Produce "build a prova di proiettile", ma è molto lento. Nessun altro sistema sarà a prova di proiettile come Scons. Ma è lento. È scritto in Python e abbiamo esteso l'interfaccia per la nostra "organizzazione dello spazio di lavoro" (dove semplicemente specifichiamo le dipendenze dei moduli), e questo fa parte dell'intento Sconsprogettuale (questo tipo di estensione tramite Python). Conveniente, ma le build sono lente. Ottieni build a prova di proiettile (qualsiasi box di sviluppatore può effettuare la versione finale), ma è lento. Ed è lento. Non dimenticare che se usi Scons, però, è lento. Ed è lento.

Mi fa male pensare che un decennio dopo l'anno 2000 non abbiamo ancora macchine volanti. Probabilmente dovremo aspettare altri cento anni o qualcosa per ottenerli. E poi probabilmente tutti voleremo in giro con le nostre macchine volanti che vengono ancora costruite con sistemi di costruzione scadenti.

Sì, sono tutti orribili.

[INFORMAZIONI SULLA GENERAZIONE DEL CODICE]

Sconsfunziona su "fasi" e sono "piuttosto statiche". Può costruire codice che viene generato come parte della build (le persone lo fanno in un paio di modi diversi), ma questo è stato descritto come "qualcosa di molto simile a Scons".

Se è semplice "preelaborare alcuni file e generare file di origine", allora non è un problema (hai molte opzioni, ed è per questo che è qmakestato scritto - per la mocpreelaborazione dei *.hpp/*.cppfile).

Tuttavia, se lo stai facendo in modo "pesante", dovrai creare il tuo script. Ad esempio, avevamo script come parte della build che richiedevano query ai database e generavano classi C ++ per interfacciarsi tra i "livelli" (nello sviluppo di applicazioni tradizionali a 3 livelli). Allo stesso modo, abbiamo generato il codice sorgente server / client tramite IDL e informazioni sulla versione incorporata per consentire l'esecuzione di più client / server contemporaneamente con versioni diverse (per lo stesso "client" o "server"). Un sacco di codice sorgente generato. Potremmo "fingere" che sia "il sistema-build", ma in realtà è un'infrastruttura non banale per la "gestione della configurazione", di cui una parte è il "sistema-build". Ad esempio, questo sistema doveva "rimuovere" e "


37
Mi piacciono anche gli Scons, ma penso che sia lento.
Lothar,

1
È possibile far sì che CMake gestisca la generazione del codice con un wrapper Makefile per eseguire una seconda fase facoltativa quando viene generato il codice. Sono stato in grado di supportare il tracciamento completo delle dipendenze, l'uscita anticipata dopo la generazione del codice per attivare un re-cmake, ecc. Vedi: javaglue.com/javaglue.html#tag:JavaGlue e code.google.com/p/javaglue
sdw

3
A quasi 2 anni di distanza, ritieni ancora lenti gli SCon? Quando stavo scegliendo un sistema di build, mi sono imbattuto in questo e questo ha contribuito alla mia decisione di andare con SCons.
JBentley,

2
@Ben, è vero, ma è anche lento.
charley,

2
Chiunque guardi questo dovrebbe considerare Meson (che usa il ninja).
Matthew D. Scholefield,

33

Puoi usare Gradle ora: https://docs.gradle.org/current/userguide/native_software.html

Questo sembra essere maturato un po 'negli anni da quando ho pubblicato questo post. La pagina che dice che il progetto è "in incubazione" è scomparsa, ma non riesco a trovare alcun annuncio ufficiale che rimuova questo stato.


Concordo con Gradle. Gradle è progettato per essere scalabile. Tuttavia, dipende dall'implementazione del plug-in quanto è veloce. C'è anche un certo sovraccarico per il livello stesso. Inoltre, tieni presente che potrebbe essere necessario personalizzare alcuni plugin per i tuoi casi d'uso.
JE42

Interessante vedere l'interesse di Gradle nel supportare il C ++. Spero che producano un sistema di costruzione bello e solido per i progetti c ++ che mancano a tutti noi.
hbobenicio,

@squid grazie, aggiornato.
Nate Glenn,

1
Gradle è potente ma semplice. Nessuna strana sintassi, un singolo file gradle.build è spesso sufficiente per costruire un intero progetto con più output eseguibili (main, test, ecc.). Nessun dump di file in tutte le directory di origine. Super amichevole per il versionning.
Overdrivr,

1
Ho passato gli ultimi due giorni a combattere con Gradle, cercando solo di creare una libreria, un'app e dei test di "ciao mondo", e non posso dire di poterlo consigliare per un nuovo progetto. Gli strumenti possono essere tutti lì, ma la documentazione non lo è (dando il beneficio del dubbio). Forse quelli di voi che lo trovano praticabile potrebbero indicare le vostre risorse preferite?
jwm,

16

Ho trovato questi, non li ho ancora usati personalmente tutti:

Ninja , un piccolo sistema di costruzione focalizzato sulla velocità. Google ora utilizza Ninja per creare Android anziché Make: link .

Shake , un sistema di generazione potente e veloce.

Tup , un sistema di build ad alte prestazioni. Design basato su algoritmi . Analisi di Tup .

Tutti ora sono multipiattaforma e supportano Windows. Non sono ancora sicuro del resto delle tue esigenze poiché, ancora, devo ancora testarle da solo. Sono utilizzati nello sviluppo commerciale, CIG raccolse Ninja. Ho usato e amo la facilità e la velocità di Ninja con un generatore di progetti. I primi due sono simili a Scons, Formica, ecc.


1
Tup rovinerà le ricerche di simboli, non giocherà bene con nessun altro sistema di compilazione (affatto, davvero), non giocherà bene con output casuali (come le classi generate da javaccon le classi interne, che sono separate in class$1.classfile), è scritto male e utilizza hack di sistema per ottenere ciò che fa. È ottimo per i piccoli sistemi; non realizzabile per progetti più grandi.
Qix - MONICA È STATA MISTREATA il

@Qix: non riesci a mantenere l'output separato dal tuo repository?
Kerrek SB,

1
@KerrekSB Puoi, ma non è questo il problema con la ricerca dei simboli. Tup usa FUSE e monta il suo middleware .tup/mnt. Quindi esegue tutti i programmi di compilazione in una cartella (ovvero .tup/mnt/@tupjob-XXXXX) come directory di lavoro per monitorare letture / scritture, applicando la configurazione di compilazione. Funziona bene, a meno che il percorso non sia memorizzato in modo assoluto (cioè con simboli). Quando si compila un file binario, il percorso del simbolo viene archiviato nel file binario stesso. Ciò significa che quando GDB tenta di caricare i simboli, cerca quel tupjobpercorso, che non esiste causando errori.
Qix - MONICA È STATA MISTREATA il

Sia Tup che Ninja sono strumenti di livello molto basso, più bassi o mai più bassi di Make. Non sono adattati al C ++. Non chiamerei nemmeno questi strumenti per costruire sistemi da soli perché mancano molte importanti funzionalità di livello superiore che i veri sistemi di costruzione offrono per gestire complessi progetti del mondo reale. Alcuni di questi sistemi possono usare Ninja come back-end.
Johan Boulé,

11

Scons è un sistema molto amichevole e flessibile, ma hai ragione, Lothar, è davvero lento.

Ma c'è un modo per aumentare le prestazioni dei programmi scritti in Python. Questo uso di JIT. Di tutti i progetti noti, PyPy è un'implementazione Python 2.7 molto potente, in rapida crescita e motivata. La compatibilità di PyPy con Python 2.7 è semplicemente sorprendente. Tuttavia, Scons ha dichiarato come progetto non supportato nel wiki di compatibilità di PyPy . Waf , invece, modellato come successore degli autotools basati su Python, è completamente supportato dall'infrastruttura PyPy. Nei miei progetti la velocità dell'assemblaggio è aumentata di 5-7 volte nel passaggio a PyPy. Puoi vedere i rapporti sulle prestazioni da PyPy .

Per un sistema di costruzione moderno e relativamente veloce, Waf è una buona scelta.


Vale la pena notare che gli scons ora sono contrassegnati come "Compatibili" sulla pagina wiki collegata, quindi apparentemente ora funziona con PyPy.
Nome falso

8

Il sistema di generazione di Google è una buona alternativa: http://bazel.io/


3
"Cross platform (Linux come obiettivo principale, ma in grado di basarsi anche su Windows)". Le FAQ di Bazel dicono "Attualmente stiamo lavorando attivamente per migliorare il supporto di Windows, ma è ancora molto lontano dall'essere utilizzabili".
Michael Mrozek,

3
Non sono sicuro che sia il sistema stesso o il ragazzo che ha impostato il progetto, ma ho avuto grossi dolori alla schiena nell'usarlo @ lavoro. È molto poco flessibile (nel senso che supporta solo un modo di fare cose, spesso non ottimale, se non inquietante), non abbastanza potente, scarsamente documentato (a parte i casi di base), ha poca comunità quindi non aspettarti che StackOverflow venga a salvarti , piuttosto una dipendenza da sola, non gioca bene con la maggior parte degli IDE sulla maggior parte dei sistemi, ecc, ecc. ecc. Quindi, a meno che tu non sia un fan di Google, stai lontano da esso (tra l'altro c'è una versione di Facebook di questo, chiamata Buck - per i fan di Facebook)
Slava il

Ehi, l'ho trovato davvero facile da usare dopo aver trascorso 6 settimane a cercare di far funzionare CMake. Volevo che scaricasse dipendenze di terze parti e le compilasse (dato che ero abituato a creare strumenti piacevoli da Python e JavaScript). Ciò ha reso semplice ma ha lo svantaggio che potresti dover scrivere i tuoi file bazel per terze parti che non lo supportano. Hanno bisogno di un repository centrale per archiviarli in questo modo.
CpILL,

6

Ho usato SCons e sono rimasto colpito da questo sistema di build. SCons è estendibile da Python e Python stesso - è fantastico, perché Python ha tutto ciò di cui hai bisogno, basta codificare la logica, tutte le funzionalità di basso livello sono già implementate in SCons e Python ed è multipiattaforma. Se hai buone capacità di programmazione, i tuoi script di costruzione appariranno perfetti e facili.

Make, CMake e sistemi di compilazione simili sembrano spazzatura di macro. Waf è un analogo SCons. Sto provando Waf ma SCons sarà più amichevole e quindi sono rimasto con SCons.

Secondo l'opinione della folla, SCons è troppo lento, ma nel mezzo di un progetto non ho visto alcuna differenza tra make e SCons in base alla velocità di costruzione. Invece, SCons ha funzionato bene con build parallele, mentre make ha grossi problemi.

Inoltre, SCons ti consente di: configurare, costruire, distribuire, generare la configurazione da modelli, eseguire test ed eseguire qualsiasi altra attività che può essere eseguita con la codifica con Python e SCons, tutto in uno. Questo è un grande vantaggio.

Per un semplice progetto CMake è anche una buona scelta.


3
Il mio problema qui è che sono viziato. Sono uno sviluppatore Java di professione e strumenti come Gradle nel mondo Java sono il tipo di strumenti che mi piacerebbe davvero avere per lo sviluppo del C ++. Posso creare un progetto gradle, senza dipendenze esterne, usando un file di build a riga singola. Questo è tutto. I progetti multi-modulo che hanno numerose dipendenze sono ancora facili da fare, e in realtà pesano con una configurazione molto meno di un semplice progetto C ++ ...
Graham,

Ho avuto problemi nella costruzione di altri pacchetti che usano Scons perché non astraggono flag di configurazione del sistema come -I include dirs e -L librerie di libreria. Non ci vorrà CFLAGS, spesso devi modificare ogni script scons per farlo apparire nel posto giusto.
ACyclic

5

solo per aggiungere i miei centesimi: premake

http://industriousone.com/premake

c'è anche una pagina web dedicata sul wiki.


2
Purtroppo Premake non supporta la generazione di codice in base ai requisiti del PO. E non definirei il suo supporto per i test unitari "decenti", anche se ci sono alcune cose che puoi fare.
ergosys,

@ergosys noto che formica non è menzionata, antsupporta anche C / C ++, vedi se questo è un bene per te, è il cognome che ho, uso solo Makefiles e Cmake per questo.
user827992,

2

Puoi usare Ceedling . Nota, tuttavia supporta solo C al momento ed è strettamente accoppiato ai framework di test Unity e CMock dell'autore.

Può essere biforcato e modificato per funzionare con un compilatore C ++ e un framework di testing / derisione unità abbastanza facilmente.

Anche Tup è una menzione degna. È estremamente veloce ma non sa nulla sui test dei framework ecc. Ciò significa che dovrai scrivere il tuo sistema di build usando Tup. Se hai intenzione di fare TDD, Tup è probabilmente la strada da percorrere.

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.