Rafael S. Calsaverini
Rafael S. Calsaverini

Reputation: 14012

Making a better Makefile

so I learned what a Makefile was some time ago, created a template Makefile and all I do is copy and alter the same file for every program I'm doing. I changed it a few times, but it's still a very crude Makefile. How should I improve it? This is an example of my current version:

CC  = g++
CFLAGS  = -std=gnu++0x -m64 -O3 -Wall  
IFLAGS  = -I/usr/include/igraph
LFLAGS  = -ligraph -lgsl -lgslcblas -lm 
DFLAGS  = -g -pg

# make all
all: run test                   

# make a fresh compilation from scratch 
fresh: clean test                

#makes the final executable binary
run: main.o foo1.o foo2.o              
    $(CC) $(CFLAGS) $(LFLAGS) $^ -o $@

#makes the test executable with debugging and profiling tags
test: test.o foo1.o foo2.o 
    $(CC) $(DFLAGS) $(CFLAGS) $(LFLAGS) $^ -o $@

#makes teste.o
teste.o: teste.cpp
    $(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@

#makes main.o
main.o:  main.cpp
    $(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@   

#file foo1
foo1.o: foo1.cpp
    $(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@   

#file foo2
foo2.o: foo2.cpp
    $(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $@   

clean: clean-test clean-o clean-annoying

clean-test:
    rm test-rfv

clean-o:
    rm *.o -rfv

clean-annoying:
    rm *~  -rfv

Just by visually comparing with other makefiles I saw around in the web, this seems to be not a very bright Makefile. I don't know how they work, but I can see there's significantly less boilerplate and more generic code in them.

Can this can be made better, safer, and easier to particularize for each project?

Upvotes: 4

Views: 1861

Answers (2)

William Pursell
William Pursell

Reputation: 212238

Do NOT use CC for the C++ compiler. The standard convention is that CC is the C compiler, CXX is the C++ compiler. CFLAGS are flags for the C compiler, CXXFLAGS are flags for the C++ compiler, and CPPFLAGS are flags for the pre-processor (eg, -I or -D flags). Use LDFLAGS for -L flags to the linker, and LDLIBS (or LOADLIBES) for -l flags.

Using the standard conventions is good not just because it makes things easier for others to understand, but also because it allows you to take advantage of implicit rules. If make needs to make a .o file from a .c file and you have not provided a rule, it will use a standard rule and honor the settings of CC, CFLAGS, and CPPFLAGS. If CC is a C++ compiler, things will probably not work.

Upvotes: 4

user2100815
user2100815

Reputation:

You don't want to name specific files in a makefile if you can get away with it, and 99% of the time you can. This page shows how to develop a very general makefile. The following is my own makefile, based on that page's info:

SHELL := bash
PROG := pathed.exe

OUTDIRS := bin/debug bin/rel obj/debug obj/rel

PROG_REL := bin/rel/$(PROG)
PROG_DEBUG := bin/debug/$(PROG)

SRCFILES := $(wildcard src/*.cpp)

OBJFILES_REL := $(patsubst src/%.cpp,obj/rel/%.o,$(SRCFILES))
OBJFILES_DEBUG := $(patsubst src/%.cpp,obj/debug/%.o,$(SRCFILES))

DEPFILES := $(patsubst src/%.cpp,obj/%.d,$(SRCFILES))

CFLAGS := -Iinc -Wall -Wextra  -MMD -MP
DBFLAGS := -g
RELFLAGS := 

CC := g++

.PHONY: default all testmake debug release clean dirs

default: debug 

all:    dirs clean debug release

dirs: 
    @mkdir -p  $(OUTDIRS)

debug:  $(PROG_DEBUG)

release: $(PROG_REL)

testmake:
    @echo OBJFILES_REL = $(OBJFILES_REL)
    @echo OBJFILES_DEBUG = $(OBJFILES_DEBUG)
    @echo SRCFILES = $(SRCFILES)
    @echo DEPFILES = $(DEPFILES)

clean:
    rm -f $(OBJFILES_REL) $(OBJFILES_DEBUG) $(DEPFILES) $(PROG)

$(PROG_REL): $(OBJFILES_REL)
    $(CC)  $(OBJFILES_REL) -o $(PROG_REL)
    strip $(PROG_REL)
    @echo "----  created release binary ----"


$(PROG_DEBUG): $(OBJFILES_DEBUG)
    $(CC) $(OBJFILES_DEBUG) -o $(PROG_DEBUG)
    @echo "----  created debug binary ----"

-include $(DEPFILES)

obj/rel/%.o: src/%.cpp
    $(CC) $(RELFLAGS) $(CFLAGS) -MF $(patsubst obj/rel/%.o, obj/%.d,$@) -c $< -o $@

obj/debug/%.o: src/%.cpp
    $(CC) $(DBFLAGS) $(CFLAGS) -MF $(patsubst obj/debug/%.o, obj/%.d,$@) -c $< -o $@

Upvotes: 6

Related Questions