ddz
ddz

Reputation: 526

build makefile with different folders in application

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

Answers (1)

Beta
Beta

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

Related Questions