Creating a Better Makefile

so I found out that the Makefile was some time ago, created a Makefile template, and all I do is copy and modify the same file for every program that I do. I changed it several times, but it was still a very rude Makefile. How can 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 because of the visual comparison with other makefiles I have seen on the Internet, this does not seem to be a very bright Makefile. I don’t know how they work, but I see there are significantly fewer templates and more general code.

Is it possible to do it better, safer and easier for each project?

+4
source share
2 answers

You do not want to specify specific files in the makefile if you can leave with it, and in 99% of cases you can. This page shows how to develop a very generic makefile. The following is my own makefile based on the information in this page:

 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 $@ 
+6
source

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

Using standard conventions is good not only because it makes others easier to understand, but also because it allows you to use implicit rules. If make needs to make a .o file from a .c file, and you did not provide a rule, it will use the standard rule and follow the CC, CFLAGS, and CPPFLAGS settings. If CC is a C ++ compiler, then everything probably won't work.

+4
source

All Articles