Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile to put object files from source files different directories into a single, separate directory?

Tags:

I'm using UnitTest++ to allow me to create unit tests for some C++ code (that should build on Linux or Mac OS X). I have a directory structure like this:

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

And this Makefile (adapted from the UnitTest++ Makefile) works nicely (with 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:     -@$(RM) -f $(objects) $(test_objects) $(test) 2> /dev/null  %.o : %.cpp     @echo $<     @$(CXX) $(CXXFLAGS) -c $< -o $(patsubst %.cpp,%.o,$<) 

But I want to put all the .o files in an "obj" subdirectory of the "test" directory. How do I modify this Makefile to do so?

I've tried adding "obj/" to the objects and test_objects variables, but I can't figure out how to modify the %.o rule so it knows where the .o files are and refers to the correct .cpp files. Do I need to create two separate rules, one for each set of .cpp files?

Would it be simpler if instead of defining the src and test_src variables, I just have the Makefile build a .o (into obj/) for all .cpp files (both in the same directory as the Makefile and in ../src/)?

like image 777
Daryl Spitzer Avatar asked Nov 04 '10 23:11

Daryl Spitzer


People also ask

What is $@ in makefile?

$@ is the name of the target being generated, and $< the first prerequisite (usually a source file). You can find a list of all these special variables in the GNU Make manual.

Can makefile target be a directory?

Yes, a Makefile can have a directory as target. Your problem could be that the cd doesn't do what you want: it does cd and the git clone is carried out in the original directory (the one you cd ed from, not the one you cd ed to). This is because for every command in the Makefile an extra shell is created.

What is Vpath in makefile?

The value of the make variable VPATH specifies a list of directories that make should search. Most often, the directories are expected to contain prerequisite files that are not in the current directory; however, make uses VPATH as a search list for both prerequisites and targets of rules.


1 Answers

There's more than one way to do it, but this is a pretty good one (I really should have that 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 $@  obj/%.o : %.cpp   @echo $<    @$(CXX) $(CXXFLAGS) -c $< -o $@ 
like image 50
Beta Avatar answered Oct 10 '22 23:10

Beta