Skip to content
Advertisement

Makefile: Cpp Files in Different Directories, Redirect Object Files to ./obj and Executable to ./bin

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement