2010-11-04 24 views
22

Sto usando UnitTest ++ per permettermi di creare test unitari per alcuni codici C++ (che dovrebbero essere basati su Linux o Mac OS X). Ho una struttura di directory simile a questo:Makefile per mettere i file oggetto da file sorgente su directory diverse in una singola directory separata?

src 
- Foo.cpp 
- Bar.cpp 
test 
- FooTest.cpp 
- BarTest.cpp 
- Main.cpp 
- Makefile 
UnitTest++ 
- libUnitTest++.a 

E questo Makefile (adattato dal unittest ++ Makefile) funziona bene (con GNU make):

test = TestFooAndBar 

src = ../src/Foo.cpp \ 
    ../src/Bar.cpp 

test_src = Main.cpp \ 
    FooTest.cpp \ 
    BarTest.cpp 

lib = ../UnitTest++/libUnitTest++.a 

objects = $(patsubst %.cpp,%.o,$(src)) 
test_objects = $(patsubst %.cpp,%.o,$(test_src)) 


.PHONY: all 
all: $(test) 
    @echo Running unit tests... 
    @./$(test) 

$(test): $(lib) $(test_objects) $(objects) 
    @echo Linking $(test)... 
    @$(CXX) $(LDFLAGS) -o $(test) $(test_objects) $(objects) $(lib) 

.PHONY: clean 
clean: 
    [email protected]$(RM) -f $(objects) $(test_objects) $(test) 2> /dev/null 

%.o : %.cpp 
    @echo $< 
    @$(CXX) $(CXXFLAGS) -c $< -o $(patsubst %.cpp,%.o,$<) 

Ma voglio mettere tutti i file .o in una sottodirectory "obj" della directory "test". Come posso modificare questo Makefile per farlo?

Ho provato ad aggiungere "obj /" alle variabili oggetti e test_objects, ma non riesco a capire come modificare la regola% .o in modo che sappia dove sono i file .o e fa riferimento alla corretta. file cpp. Devo creare due regole separate, una per ogni set di file .cpp?

Sarebbe più semplice se invece di definire le variabili src e test_src, ho solo il Makefile compilare un file .o (in obj /) per tutti i file .cpp (entrambi nella stessa directory del Makefile e in ../src /)?

risposta

36

C'è più di un modo per farlo, ma questo è abbastanza buono (dovrei davvero avere quel tasto di scelta rapida).

vpath %.cpp ../src 

src = Foo.cpp Bar.cpp 
test_src = Main.cpp FooTest.cpp BarTest.cpp 

objects = $(patsubst %.cpp,obj/%.o,$(src)) 
test_objects = $(patsubst %.cpp,obj/%.o,$(test_src)) 

$(objects): | obj 

obj: 
    @mkdir -p [email protected] 

obj/%.o : %.cpp 
    @echo $< 
    @$(CXX) $(CXXFLAGS) -c $< -o [email protected] 
+7

Che cosa significa "|" nella riga '$ (oggetti): | obj' sta per? –

+15

@mezhaka, significa che i prerequisiti che seguono (in questo caso 'obj') sono [prerequisiti di solo ordine] (http://www.gnu.org/software/make/manual/make.html#Prerequisite-Types). Ciò significa che se qualche '$ (objects)' deve essere compilato allora 'obj' deve essere costruito per primo, ma se' obj' non è aggiornato (o non esiste), ciò * non * forza '$ (oggetti) 'da costruire. – Beta

+0

funziona come un fascino. –

Problemi correlati