2010-03-02 16 views
42

Qual è una buona struttura di directory per progetti C++ più grandi che utilizzano Makefile?Qual è una buona struttura di directory per progetti C++ più grandi che utilizzano Makefile?

Ecco come il mio struttura di directory guarda in questo momento:

lib/ (class implementations *.cpp) 
include/ (class definitions *.h) 
tests/ (main.cpp for quick tests) 

Ora, io non sono sicuro di come il mio Makefile dovrebbe essere simile ... non sembra funzionare quando i file cpp e .h i file non si trovano nella stessa directory. Qualcuno potrebbe indicarmi una struttura di directory comune con un Makefile di accompagnamento in modo da non reinventare la ruota?

+0

Hai un Makefile attualmente? Se è così, potresti prendere in considerazione di postare per ottenere un feedback specifico –

+0

usare il Make VPATH = ../lib: ./ include renderà l'intestazione disponibile nella tua directory di test –

risposta

51

Separare il file. Cpp del file .h non è sempre una buona soluzione. Generalmente li separo entrambi quando è usato come libreria (intestazione pubblica in include e intestazione privata con il codice sorgente).

Se è una libreria, questa struttura è ok.

lib/ (class implementations *.cpp .h) 
include/ (class definitions *.h) <- Only those to be installed in your system 
tests/ (main.cpp for quick tests) 
doc/ (doxygen or any kind of documentation) 

Se si tratta di un'applicazione

src/ (source for the application) 
lib/ (source for the application library *.cpp *.hpp) 
include/ (interface for the library *.h) 
tests/ (main.cpp for quick tests) <- use cppunit for this part 
doc/ (doxygen or any kind of documentation) 

Utilizzare il flag -I $ (PROJECT_BASE)/comprendono per specificare il percorso includono per la compilazione

Se si tratta di un grande progetto, può essere buono usare lo strumento come autoconf/automake o cmake per costruire tutto. Faciliterà lo sviluppo.

+4

Non capisco. Qual è la differenza tra 'src' e' lib'? – feeela

+1

Quando un'applicazione è troppo grande, si desidera separare il programma in un modulo diverso. Modulo che può essere indipendente e riutilizzabile in altre applicazioni. Quindi potresti scriverlo come lib/LibraryForLogging, lib/LibraryForDatabase etc ... È più facile da gestire rispetto a se fosse stato mixato con tutto il codice sorgente. – Phong

+0

Questo sembra un modo semplice per farlo, ma per quanto riguarda le cartelle di output (create file)? Diciamo che voglio creare una libreria (senza installarla), quale cartella dovrei inserire? – gromit190

6

Non esiste una "buona struttura di directory". Scegli una struttura con cui ti trovi comodo e attenendoti. Alcuni preferiscono posizionare file sorgente (intestazioni e file di implementazione) in una directory src/, quindi la directory radice del progetto non ha altro che un makefile, un readme e poco altro. Alcuni, come collocare le librerie di supporto in una directory lib/, Unittests sotto test/ o src/test/, la documentazione sotto doc/ ecc

non ho ancora sentito nessuno dividere file di intestazione e file di implementazione in due directory distinte però. Personalmente non mi piace molto dividere i file in directory. Solitamente colloco tutti i miei sorgenti in un'unica directory e tutta la documentazione in un'altra directory. Se mi baso comunque su buoni strumenti di ricerca, non c'è bisogno di una struttura di directory complessa.

make può gestire il tipo di struttura in cui il makefile risiede in una directory diversa dalla sorgente. L'unica cosa è che invocherà le regole dalla directory del makefile - i compilatori di solito non hanno problemi a compilare la fonte che si trova in qualche sottodirectory. Non è necessario specificare percorsi relativi nei tuoi #include s; basta specificare il percorso di inclusione con i flag del compilatore (flag di gcc -I ecc.).

+5

e 'bin /' per gli eseguibili ... :) – Lipis

12

Se si dispone di molti file sorgente, potrebbe anche essere una buona idea suddividere ulteriormente la directory di origine. Per esempio, una sottodirectory per la funzionalità di base della vostra applicazione, uno per l'interfaccia grafica, ecc

src/core 
src/database 
src/effects 
src/gui 
... 

In questo modo anche ti costringe a evitare rapporti non necessari tra i tuoi "moduli", che è un prerequisito per bella e riutilizzabile codice.

12

Non esiste una struttura di directory specifica o obbligatoria.

È possibile configurarlo in qualsiasi momento. Il tuo problema è semplice da risolvere. Basta istruire Makefile per cercare nelle sottodirectory o inserire oggetti compilati in sottodirectory invece di usare solo la directory corrente.

Si sarebbe solo utilizzare nei percorsi di Makefile:

%.o : %.cpp 

sostituirli con

bin/%.o : %.cpp 

Così sarà verificare se il file binario nella directory bin esiste e così via, è possibile applicare lo stesso a posizioni dove i file sono compilati.

Esistono modi per aggiungere/rimuovere/modificare percorsi di file di origine e oggetto.

Dai un'occhiata alla gnu make manual, in particolare la sezione 8.3 Funzioni per i nomi di file, e quello prima ancora 8.2 Funzioni per la stringa di sostituzione e analisi.

È possibile fare cose come:

ottenere un elenco di oggetti dalla lista dei file sorgenti nella directory corrente:

OBJ  = $(patsubst %.cpp, %.o, $(wildcard *.cpp)) 

uscita:

Application.o Market.o ordermatch.o 

Se oggetti binari sono in sottodirectory bin ma il codice sorgente è nella directory corrente è possibile applicare il prefisso bin ai file oggetto generati:

OBJ  = $(addprefix bin/,$(patsubst %.cpp, %.o, $(wildcard *.cpp))) 

uscita:

bin/Application.o bin/Market.o bin/ordermatch.o 

E così via.

Problemi correlati