0
votes

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.

1
OBJS = $(addprefix $(OBJDIR), _OBJS) is a syntax error, you want to put also_OBJS inside $() as the string without it is just the string itself, not the variable contents. Also $(OBJDIR) obj/%.o is wrong. You wanted to say $(OBJDIR)/%.o. At last, name your first target out and not all. It creates this file, so no need to confuse make and the reader with a rule which does not produce its target.Vroomfondel

1 Answers

0
votes

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.