Makefile quick how-to

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:

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.