2010-11-04 7 views
22

J'utilise UnitTest ++ pour me permettre de créer des tests unitaires pour du code C++ (qui devrait s'appuyer sur Linux ou Mac OS X). J'ai une structure de répertoires comme ceci:Makefile pour placer les fichiers objets des fichiers source différents répertoires dans un seul répertoire séparé?

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

Et ce Makefile (adapté du UnitTest ++ Makefile) fonctionne bien (avec 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,$<) 

Mais je veux mettre tous les fichiers .o dans un sous-répertoire "obj" du répertoire "test". Comment puis-je modifier ce Makefile pour le faire?

J'ai essayé d'ajouter "obj /" aux variables objets et test_objects, mais je n'arrive pas à comprendre comment modifier la règle% .o pour qu'elle sache où se trouvent les fichiers .o et fasse référence à la bonne. fichiers cpp. Dois-je créer deux règles distinctes, une pour chaque ensemble de fichiers .cpp? Serait-il plus simple si, au lieu de définir les variables src et test_src, je n'ai que Makefile construire un .o (en obj /) pour tous les fichiers .cpp (à la fois dans le même répertoire que le Makefile et dans ../src /)?

Répondre

36

Il y a plus d'une façon de le faire, mais c'est une très bonne option (je devrais vraiment avoir cette touche raccourci).

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

Qu'est-ce que le "|" dans la ligne '$ (objets): | obj' représente? –

+15

@mezhaka, cela signifie que les conditions préalables qui suivent (dans ce cas 'obj') sont [conditions préalables à la commande] (http://www.gnu.org/software/make/manual/make.html#Prerequisite-Types). Cela signifie que si un '$ (objets)' doit être construit alors 'obj' doit être construit en premier, mais si' obj' est obsolète (ou n'existe pas), cela ne * force * pas $ (objets) 'à construire. – Beta

+0

fonctionne comme un charme. –

Questions connexes