Reputation: 526
I am trying to creat a makefile for my project, but I really don't understand this devil thing.
When I was doing it in Java, with ant, it was much more simplier.
The structure of my program is: http://imageshack.com/a/img39/6592/jsxa.png
I read about creating makefiles but, when they answer a question similiar, they just put the done makefile and don't explain a lot about what they're doing.
So, what I need to do is create a makefile that stay in a folder named foo (foo/makefile) together with the src folder(foo/src/). The makefile needs to create a folder named bin (foo/bin/) and put *.o files in there. Then build the program (DisqueRango.cpp contais the main function) and run it using 4 arguments: "-e couriers.csv -c menu.csv".
I'm not asking for the done makefile. What I need is an explanation about what I need to do it by myself.
Thank you indeed.
makefile of src/clients/
CC := g++
OBJ = *.cpp
all: prog
prog:
$(CC) -c $(OBJ)
makefile of src/disquerango/ (contais main function)
CC := g++
BASEDIR := ..
MODULES := clients couriers products read requests
OBJS := $(addsuffix /*.o, $(addprefix $(BASEDIR)/,$(MODULES)))
.PHONY: clean
all:
$(CC) -o disquer DisqueRango.cpp $(OBJS)
and the makefile who call them all (same folder of src):
CC := g++
BASEDIR := src
PROJN := disquerango
MODULES := clients couriers products read requests disquerango
OBJS := $(addprefix $(BASEDIR)/,$(MODULES))
all: compila run limpa
compila:
for dir in $(OBJS); do (cd $$dir; ${MAKE} all); done
run: compila
./$(BASEDIR)/$(PROJN)/disquer -e entregadores.csv -c cardapio.csv
limpa:
rm -f $(BASEDIR)/$(PROJN)/disquer
for dir in $(OBJS); do (cd $$dir; rm -f *.o); done
Upvotes: 0
Views: 1047
Reputation: 99114
This may take a few iterations. You must start with the small and simple, and work up to the large and complex.
First, create bin/
yourself.
Now write a makefile that can build one object file:
bin/DisqueRango.o: src/DisqueRango.cpp
g++ -c src/DisqueRango.cpp -o bin/DisqueRango.o
Get that working, and understand how it works, post a comment to tell us the result, and we'll proceed.
EDIT:
src/clients/makefile:
CC := g++
OBJ = *.cpp
all: prog
prog:
$(CC) -c $(OBJ)
This makefile is effective but crude. It will rebuild all objects every time it is run, even if they are already up to date. We could add another command, mv *.o ../../bin
, which would put them all into bin/
, but I think it is better to improve the basic structure now, while the clients
codebase is still simple.
The statement OBJ = *.cpp
gives the variable OBJ
the value *.cpp
; the wildcard will not be expanded until the variable is used in the shell command. To assign a list of files to the variable, we use the wildcard
function. To transform a list of source files (foo.cpp
) into a list of object files (foo.o
), we use the patsubst
function. To build the object files we use a pattern rule, and within that rule we use automatic variables to refer to the source file (foo.cpp
) and the target (foo.o
).
CC := g++
SRC := $(wildcard *.cpp) # foo.cpp bar.cpp baz.cpp
OBJ := $(patsubst %.cpp,%.o,$(SRC)) # foo.o bar.o baz.o
all: $(OBJ)
%.o: %.cpp
$(CC) -c $< -o $@
Test that much to verify that it works. Now to have this makefile put the object files in bin/
, we make a small change:
CC := g++
BIN := ../../bin
SRC := $(wildcard *.cpp)
OBJ := $(patsubst %.cpp,$(BIN)/%.o,$(SRC))
all: $(OBJ)
$(BIN)/%.o: %.cpp
$(CC) -c $< -o $@
Verify that that much works, and we'll move on to src/disquerango/makefile
.
Upvotes: 1