my directory structure looks like this
-Project |--bin |--obj/ |--class1 |--class1.h |--class1.cpp |--test |--test-wrapper-class.h |--test-wrapper-class.cpp |--main.cpp
I would like to write a Makefile that will
1) create three object files, main.o, class1.o and test-wrapper-class.o and place those files in the obj directory
2) use those object files to create an executable that will be placed in the bin folder
3) have a clean that will delete all files in obj and bin
I know how to create the object files. I have seen examples that create object files from cpp files located ALL IN THE SAME DIRECTORY then placing them all in an obj directory. What I do not know how to do is
1) to create object files from cpp source in different directories, placing all the object files in a separate directory from each of the source directories
2) and use those object files to create an executable located in yet another directory from the object files and the source.
In its current state. my Makefile does not even come close to doing the job.
CXX=g++ INC=-I/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include ./test_bench/ ./src/ LIB=-L/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/lib-linux64 LIBS=-lsystemc OBJDIR=obj _OBJS = main.o test_bench.o OBJS = $(addprefix $(OBJDIR), _OBJS) all: $(OBJS) $(CXX) $(OBJS) $(INC) $(LIB) $(LIBS) -o out $(OBJDIR) obj/%.o : %.cpp test_bench.h $(CXX) $(OBJS) $(INC) $(LIB) $(LIBS) $< -o $@
I think I pretty well understand how to include header file (library) directories and how to include the linker files. It is just moving files around during stages of compilation that I do not understand very well.
Thanks.
Advertisement
Answer
Let’s start with a simple version of this problem:
src/ foo.cpp bar.cpp inc/ bar.h obj/ bin/
I want to build foo.o
and bar.o
in obj/
, foo.cpp
includes bar.h
(so that bar.h
ought to be a prerequisite of both foo.o
and bar.o
), and I want to link those objects to build app
in bin/
.
Trick one, use full path names of targets:
SRCDIR := src INCDIR := inc OBJDIR := obj BINDIR := bin OBJECTS:= $(addprefix $(OBJDIR)/, foo.o bar.o) bin/app: $(OBJECTS) $(CXX) $^ -o $@ $(OBJECTS): $(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(CXX) -I$(INCDIR) $< -o $@ $(OBJDIR)/foo.o $(OBJDIR)/bar.o: $(INCDIR)/bar.h
Now let’s suppose that the sources are in more than one directory, such as class1/
and test/
:
Trick 2, use vpath to find sources:
vpath %.cpp src $(OBJECTS): $(OBJDIR)/%.o: %.cpp $(CXX) -I$(INCDIR) $< -o $@
And don’t forget a clean
rule:
.PHONY: clean clean: @rm -fr $(BINDIR)/* $(OBJDIR)/*
Other improvements are possible, but this is enough to get you started.