The purpose of the make utility is to determine automatically which pieces of your large program needs to be re-compiled, and issue the commands to recompile them. The make program uses the makefile instructions and the last modified time of the files to decide which of the files needs to be updated.
A makefile tells make what to do. The make utility executes commands in the makefile to update one or more targets. If -f option is not provided, make looks for the makefiles GNUmakefile, makefile, and Makefile, in that order.
Key Points
1. Make is a software engineering tool which helps simplifies the process of software development
2. Makefiles can be used to automate the build process (Generation of binary from source files)
3. The programmer does not need to type the complex compiler commands and flags to be used during compilation
1. Variables
1. A variable in a makefile can be a recursively expanded variable
NAME = value or a simply expanded variable
NAME := value
2. The variable's value can be accessed using
$(NAME) or
${NAME}
3. As a convention, the variable names are always written in uppercase.
4. Variable names are case-sensitive and should not contain other than letters, numbers and underscores as they may have a special meaning
5. Setting a variable if not already set use
?= e.g.
NAME ?= value
Note: You cannot append a value at the end of the recursively expanded variable using
CC = $(CC) -O2. This will end up in an infinite loop as make will continue expanding this variable until it cannot be expanded anymore. To overcome this problem, we use simply expanded variables to append values at the end as shown
CC := g++ -o
CC += $(CC) -O2
2. Explicit Rules
Explicit rules tell make which files depend on the compilation of other files and the commands required to compile those files. They take the following form:
targetfile : dependentfiles
[TAB]commands
...
[TAB]commands
3. Implicit Rules or Suffix Rules
Implicit rules are similar to explicit rules except that they are listed without commands. The make utility makes uses of the file suffixes to determine what commands to execute on the source files
hello.o : hello.c
Running make will cause the following command to be executed
cc -c -o hello.o hello.c
Common variables used by implicit rules:
AR : archive program, default ar
CC : compiling c program, default cc
CXX : compiling c++ program, default g++
CPP : c preprocessor, default $(CC) -E
RM : remove, default rm -f
Flags used by the programs above
ARFLAGS : flags for the archive program, default rv
CFLAGS : flags for the c compiler
CXXFLAGS : flags for the c++ compiler
CPPFLAGS : flags for the c preprocessor
LDFLAGS : flags for the linker
Some of the old fashioned suffix rules for C and C++ are:
Compiling C Programs
file.o is automatically built from file.c. $(CC) -c $(CPPFLAGS) $(CFLAGS)
Compiling C++ Programs
file.o is automatically built from file.cc. $(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
Linking Object Files
file is automatically generated from file.o by running the linker (ld). $(CC) $(LDFLAGS) file.o $(LOADLIBS) $(LDLIBS)
The default suffix list for common C and C++ programs include
.out, .a, .o, .c, .cc, .C, .def, .h. The complete list can be found out
here
The above catalogue of implicit rules are always available unless makefile explicitely overrides them. Running make with
-r or
--no-builtin-rules option cancels all predefined rules
Implicit rules can also be disabled by disabling default suffixes and having only the suffixes you need
.SUFFIXES: # Delete the default suffixes
.SUFFIXES: .c .cpp .o .h # Define our suffix list
Inference Rules: Inference rules are rules distinguished by the use of the character “%” in the dependency line. The “%” (rule character) is a wild card, matching zero or more characters. As an example, here is an inference rule for building .obj files from .c files:
%.obj : %.c
$(CC) $(CFLAGS) –c $(.SOURCE)
4. Phony Targets
A phony target is one that is not really the name of the target file. It is a request for executing a set of commands that should not create the target file name. As the target file will never exist, the commands will be executed always e.g.
clean:
rm *.o temp
You can also explicitely declare a target as phony using the special target .PHONY
.PHONY = clean
5. Comments
A comment starts with
# character in a makefile
6. Substitution References
A substitution reference has the form
$(file:.c=.o). The below example sets
OBJFILES to
a.o b.o c.o
SRCFILES = a.c b.c c.c
OBJFILES = $(SRCFILES:.c=.o)
SRCFILES = a.c b.c c.c
OBJFILES = $(SRCFILES:%.c=%.o)
Read more ...