2012-07-26 16 views
6

Ho un numero di file C++ distribuiti in diverse cartelle.Come ottenere file cpp da diverse directory compilate in una cartella?

a_library/ 
    file1.cpp 
    file2.cpp 
    category1/ 
     file3.cpp 
     file4.cpp 

Sono garantiti per essere denominati in modo univoco. Voglio compilare tutti questi file C++ per separare i file oggetto nella directory obj/.

Ho un elenco di tutti i file di origine con relativo percorso e i corrispondenti nomi di destinazione.

a_library/file1.cpp 
a_library/file2.cpp 
a_library/category1/file3.cpp 
a_library/category1/file4.cpp 

obj/file1.obj 
obj/file2.obj 
obj/file3.obj 
obj/file4.obj 

Come posso fare una regola che permette di convertire un file C++ dal primo elenco a un oggetto file dalla seconda?

Questi tentativi fare non lavoro:

obj/%.obj: %:cpp 
    # ... 

%.obj: %.cpp 
    # ... 

.cpp.obj: 
    # ... 

vorrei non scrivere le regole di questo tipo:

obj/%.obj: a_library/%.cpp 
    # ... 

obj/%.obj: a_library/category1/%.cpp 
    # ... 

risposta

5

provare a impostare VPATH:

VPATH = a_library:a_library/category1 
obj/%.o: %.cpp 
    $(CXX) -c $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) -o [email protected] $< 

e di aggiungere all'elenco dei file completo (vi consiglio di esplicitamente elencare i file, non utilizzare $(wildcard ...) funzione) e il collegamento della domanda:

files := main.cpp $(wildcard a_library/*.cpp) a_library/category1/file.cpp 

obj/application: $(patsubst %.cpp,obj/%.o,$(notdir $(files))) 
    $(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) -o [email protected] $+ 

Il $(wildcard) ha una tendenza fastidiosa a raccogliere qualsiasi cosa nelle directory, come singoli file di test o provvisori (se hanno un nome appropriato: ~file.cpp).

1

Una soluzione che posso pensare: basta costruire loro inplace con un semplice regola e quindi crea una "fase di raccolta" spostando i file ".o" in una singola cartella.

Crea un target "collect_objs" che dipende dal tuo $ (OBJS) e quindi il tuo target "principale" deve dipendere da "collect_objs".

L'attraversamento può essere fatto utilizzando guscio

dirs := $(shell find ./ -type d) 
collect_objs: $(dirs) 
     for d in $+; do \ 
      mv *.o YourDestDir/*.o 
     done 

Naturalmente, questo implica utilizzando il pacchetto UnxUtils (con 'trovare' e 'mv') o Cygwin dal momento che siete su Windows.

L'altra opzione consiste nel generare gli obiettivi per ciascuno dei file .c/.cpp in modo esplicito, utilizzando alcuni strumenti. Grab pitone, directory di origine traslazione e per ogni file .c/cpp scrivere

obj/file_name.o: 
     gcc -c path/fo/file_name.c -o obj/file_name.o 
0

Usa cmake per rendere la configurazione di generazione per voi.

Qualche tempo fa ho impostato un semplice progetto di esempio su github.

0
Non

strettamente correlato a questa domanda in quanto non ha a che fare con Make, anche se mi piacerebbe mostrare come compilo i miei progetti ora, 3 anni dopo. Craftr è un sistema di meta build basato su Python che incoraggia le build indirette fuori dall'arca (ad esempio un build nell'albero di lavoro). Costruire file oggetto e cresta una libreria statica è facile come

# craftr_module(my_project) 
from craftr import * 
from craftr.ext.platform import cxx, ar 
objects = cxx.compile(
    sources = path.platform('**/*.cpp'), 
) 
lib = ar.staticlib(
    output = 'myproj', 
    inputs = [objects], 
) 

Esecuzione craftr -eb si tradurrà con la seguente struttura dei prodotti di build

Craftfile 
file1.c 
file2.c 
category1/ 
    file3.c 
    file4.c 
build/ 
    my_project/ 
    obj/ 
     file1.o 
     file2.o 
     category1/ 
     file3.o 
     file4.o 
    libmyproj.a