Many years ago, I was considering myself as a specialist of Makefiles … But now, I know that Makefile science is not like bicycle and you may loose all this knowledge as soon as you start to java Code …
So I’ve to go back to Makefile school again and here are some of my googling notes on this topic for my own remembers and why not yours !
So I’m sorry if you are beginning Makefile, I’ll not be back on beginning stuff but it can be found here, where I started to take a look.
Let’s start with some variable definition :
# CX defines compiler to be used # CFLAGS defines the compilation flags to be used # CDEFS defines the compilation #define to be added CX=g++ CFLAGS=-c -O3 CDEFS=-DDEBUG
Let’s continue with a standard compilation rule for cpp to objects :
%.o: %.cpp $(CX) $(CFLAGS) $(CDEFS) $< -o $@
The special variables that can be used in a Makefile are
- $@ – Target value (%.o in the line above)
- $< – First value in the dependency list
- $^ – Full dependency list
- $? – Dependency value newer than target
- $* – File name w/o suffix (% in the line above)
So, this applied to the following values gives :
foo.o : foo.cpp g++ -c -O3 -DDEBUG foo.cpp -o foo.o
Know we can manage a list of source and object file for the project using variables
SOURCES=foo.cpp bar.cpp OBJECTS=$(SOURCES:.cpp=.o)
Object list is automatically generated from source list by changing the suffix value. This is corresponding to function $(patsubst %c.,%.o,list…)
Some other text processing function are interesting to be used:
- $(dir list) – returns pathname of the files in list
- $(notdir list) – returns basename (including extension) of the files in list
- $(suffix list) – returns the file extension of the files in the list
- $(basename list) – returns path + basename (excluding extension) of the files in list
- $(addsuffix suffix,list) – add an extension (like .o .c) to the given list
- $(addprefix pref,list) – add a prefix to the list of files
Eventually it is possible to change the Path by doing something like
SOURCES=src/foo.cpp src/bar.cpp OBJECTS=helper_objects=$(addsuffix .o,$(addprefix $(OBJ_DIR)/,$(basename $(notdir $(SOURCES)))))
This can be applied as :
obj/%.o: src/%.cpp src/%.h $(CX) $(CFLAGS) $(CDEFS) $< -o $@ gives obj/foo.o : src/foo.c g++ -c -O3 -DDEBUG src/foo.cpp -o obj/foo.o
To automatically manage dependencies, it is possible to add the -MMD option to the CFLAGS
Some detailed informations: