2010-11-04 9 views
22

Używam UnitTest ++, aby umożliwić mi tworzenie testów jednostkowych dla kodu C++ (który powinien być zbudowany na systemie Linux lub Mac OS X). Mam struktura katalogów tak:Makefile do umieszczania plików obiektowych z plików źródłowych różnych katalogów w jednym, osobnym katalogu?

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

I to Makefile (zaadaptowane z unittest ++ Makefile) działa ładnie (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,$<) 

Ale chcę umieścić wszystkie .o plików w podkatalogu "obj" katalogu "test". Jak mogę zmodyfikować ten Makefile, aby to zrobić?

Próbowałem dodać "obj /" do zmiennych obiektów i test_objects, ale nie mogę wymyślić, jak zmodyfikować regułę% .o, aby wiedział, gdzie znajdują się pliki .o i odnosi się do poprawnych. pliki cpp. Czy muszę utworzyć dwie oddzielne reguły, po jednej dla każdego zestawu plików .cpp?

Czy byłoby prostsze, gdyby zamiast definiować zmienne src i test_src, po prostu mam Makefile kompilować .o (do obj /) dla wszystkich plików .cpp (zarówno w tym samym katalogu co Makefile, jak i .../src /)?

Odpowiedz

36

Istnieje więcej niż jeden sposób, aby to zrobić, ale jest to całkiem niezły (naprawdę powinienem mieć to skrót).

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

Co oznacza "|" w wierszu '$ (obiekty): | obj' oznacza? –

+15

@mezhaka, oznacza to, że następujące warunki wstępne (w tym przypadku "obj") to [wymagania wstępne dotyczące tylko zamówienia] (http://www.gnu.org/software/make/manual/make.html#Prerequisite-Types). Oznacza to, że jeśli jakieś '$ (obiekty)' musi zostać zbudowane, to 'obj' musi być najpierw zbudowane, ale jeśli' obj' jest nieaktualne (lub nie istnieje), to * nie * wymusza '$ (obiekty) 'do zbudowania. – Beta

+0

działa jak urok. –

Powiązane problemy