2010-11-04 15 views
22

Estoy usando UnitTest ++ para permitirme crear pruebas unitarias para algunos códigos C++ (que deberían basarse en Linux o Mac OS X). Tengo una estructura de directorios como esto:Makefile para poner los archivos de objetos de los archivos fuente en diferentes directorios en un solo directorio separado?

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

Y esto Makefile (adaptado del unittest ++ Makefile) funciona muy bien (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,$<) 

Pero quiero poner todos los archivos .o en un subdirectorio "obj" del directorio "prueba". ¿Cómo modifico este Makefile para hacerlo?

He intentado agregar "obj /" a los objetos y las variables test_objects, pero no puedo entender cómo modificar la regla% .o para que sepa dónde están los archivos .o y se refiere a la correcta. archivos cpp. ¿Debo crear dos reglas separadas, una para cada conjunto de archivos .cpp?

Sería más sencillo si en lugar de definir las variables src y test_src, solo tengo la compilación Makefile un .o (en obj /) para todos los archivos .cpp (tanto en el mismo directorio como en el Makefile y en ../src /)?

Respuesta

36

Hay más de una forma de hacerlo, pero esta es una muy buena (realmente debería tener ese hotkeyed).

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é significa "|" en la línea '$ (objetos): | obj' significa? –

+15

@mezhaka, significa que los requisitos previos que siguen (en este caso 'obj') son [requisitos previos de solo pedido] (http://www.gnu.org/software/make/manual/make.html#Rerequisite-Types) Esto significa que si debe construirse cualquier '$ (objetos)', entonces 'obj' debe construirse primero, pero si' obj' está desactualizado (o no existe), eso no * force * $ (objects) 'para ser construido. – Beta

+0

funciona como un encanto. –

Cuestiones relacionadas