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 shownCC := 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.cRunning 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 hereThe 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 rulesImplicit 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 makefile6. 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)
7. Conditional Statements
A conditional statement example
libs_win32 = ${win32} libs_linux = ${linux} ifeq ($(PLATFORM), linux) libs=$(libs_linux) else libs=$(libs_win32) endif hello : $(objects) $(CC) -o foo $(objects) $(libs)
8. Functions
A number of functions are provided for manipulating the text. A function call resembles a variable reference and looks like
$(FUNCTION_NAME ARGUMENTS)
Some of the commonly used text functions are:
$(subst FROM, TO, TEXT) $(strip STRING) $(findstring FIND, IN) $(sort LIST)
The
shell
function performs the same function that backquotes ``
perform, i.e. command expansion e.g.output := $(shell uname -s)
9. Automatic Variables
Few important automatic variabels are
$a : this is the target name $< : the name of the first prerequisite $^ : the name of all the prerequisite (dependentfiles) $% : the target member name, when the target is an archive e.g. if the target is hello.a(hello.o), then $% is hello.o and $@ is hello.a. $% is empty when the target is not an archive $? : the name of all the prerequisite (dependent files) which are newer than the target $* : the name of the target without the suffix e.g. if the target is hello.a, then $* is hello
For more details about using make and the syntax of the commands to use, type info make
. This will show you up with an exhaustive list of the things you can do with makefiles, definitions and uses.
Reference:
Make Tutorial
No comments :
Post a Comment