Make & Makefile

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 35

Make & Makefile

Introduction
What is a Makefile?
- A text file containing rules that define how a Make works.
What is a Make?
- Utility to maintain, update, and regenerate groups of programs
What is a rule?
- A rule tells Make both when and how to make a file
Advantages:
- Automatically rebuild a program whenever one of the source files is
modified.
- It only recompiles the files that were affected by changes, thus saving
compiling time.
Makefile Syntax
Target Rule:
target1 target2 target3 : prerequisite1 prerequisite2(dependencies)
command1
command2
command3
A target is usually name of the field that make creates; examples are
executable or object files.
A prerequisite is one or more files used as input to create targets.
A command is an action that make carries to create or update a target file
when any of the prerequisites are changed.
Each command to be executed in a rule is interpreted by a shell.
General example
Cake: eggs,milk,sugar,mix,icing
mix && bake && ice
Icing: powdered sugar,water
mix sugar + water
A simple Makefile
Example 1
Example 2
Makefile with Variables
Makefile with Automatic Variables

Some Automatic variables:


$@: The filename representing the target.
$<: The filename of the first prerequisite.
$?: The names of all prerequisites that are newer than the target, separated by
spaces.
$*: The stem of the target filename.
Rules
Make will execute the command script of the rule if any of the
prerequisite files has been modified more recently than the target.
Different kind of rules:
-Explicit rules
-Pattern rules
-Implicit rules
-Static Pattern rules
Phony Targets
Targets that do not represent files are known as phony targets.
Standard phony target is clean:
clean:
rm -f *.o lexer.c
Phony targets will always be executed because the commands associated
with the rule do not create the target name.
Need for .PHONY?
.PHONY: clean
clean:
rm -f *.o lexer.c
By this,make will always execute the commands associated with clean
even if a file named clean exists.
Variables
:,# and = are not allowed in variable names
Case sensitive
$() to get the value of a variable
During assignment of values to variables, leading spaces are trimmed;
trailing spaces are not trimmed.
Use of variables
- to hold constants
-to store user defined command sequence such as
free-space := df . | awk 'NR = = 2 { print $4 }'
Variable Types
Simply expanded variables
MAKE_DEPEND := $(CC) M

Recursively expanded variables


MAKE_DEPEND = $(CC) M
Each time the recursive variable is used, its righthand side is reevaluated.
Example:-SET_TIME=date

?= conditional variable assignment operator: This operator will perform the


requested variable assignment only if the variable does not yet have a value.

recursive = $(recursive) new stuff


$ make
makefile:2: *** Recursive variable `recursive' references itself (eventually). Stop.
+= append operator: values on the righthand side of the assignment are appended
to the variable without changing the original values in the variable.
Macros
A Macro is one that can contain embedded newlines.(i.e; multiline values)
- define directive
define <variable-name>
line1
line2.
endef
Example:-
define create-jar
@echo Creating $@...
$(RM) $(TMP_JAR_DIR)
$(MKDIR) $(TMP_JAR_DIR)
$(CP) -r $^ $(TMP_JAR_DIR)
cd $(TMP_JAR_DIR) && $(JAR) $(JARFLAGS) $@ .
$(JAR) -ufm $@ $(MANIFEST)
$(RM) $(TMP_JAR_DIR)
endef

$(UI_JAR): $(UI_CLASSES)
$(create-jar)
Rules for expanding variables
When make runs, it performs its job in two phases:
In the first phase, make reads the makefile and variables are assigned and
expanded and the dependency graph is created.
In the second phase, make analyzes the dependency graph and
determines the targets that need to be updated, then executes command
scripts to perform the required updates. So when command scripts are
being executed, all variable processing has already completed.
For variable assignments, the lefthand side of the assignment is always
expanded immediately when make reads the line during its first phase.
For macro definitions (those using define), the macro variable name is
immediately expanded and the body of the macro is deferred until used.
For rules, the targets and prerequisites are always immediately expanded
while the commands are always deferred.
Target-specific variables
gui.o: gui.h
$(COMPILE.c) -DUSE_NEW_MALLOC=1 $(OUTPUT_OPTION) $<
The general syntax for target-specific variables is:
target...: variable = value
target...: variable := value
target...: variable += value
target...: variable ?= value
The variable assignment is not actually performed until the processing of
the target begins.
Make p (or) --print-data-base

Example:
gui.o: CPPFLAGS += -DUSE_NEW_MALLOC=1
gui.o: gui.h
When the gui.o target is finished, CPPFLAGS will revert to its original value.
Pattern-specific Variables
Syntax:
pattern ... : variable-assignment
If a target matches more than one pattern, the matching pattern-specific
variables with longer stems are interpreted first.
%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
lib/%.o: CFLAGS := -fPIC -g
%.o: CFLAGS := -g
all: foo.o lib/bar.o
Override directive
Environment Variables
Conditional directive
Syntax:
if-condition
text if the condition is true
endif
or
if-condition
text if the condition is true
else
text if the condition is false
endif
The if-condition can be one of:
ifdef variable-name ------ dont use $()
ifndef variable-name
ifeq test ------ a b
ifneq test ------ (a,b)
Include directive
Syntax: include filenames
When make processes an include directive, it suspends reading of the
containing makefile and reads from each listed file in turn. When that is
finished, make resumes reading the makefile in which the directive
appears.
Built-in functions
Syntax: $(function-name arg1[, argn])
String functions
$(filter pattern...,text)
Example:
words := he the hen other the%
get-the:
@echo he matches: $(filter he, $(words))
@echo %he matches: $(filter %he, $(words))
@echo he% matches: $(filter he%, $(words))
@echo %he% matches: $(filter %he%, $(words))
$(filter-out pattern...,text)
Example:
all_source := count_words.c counter.c lexer.l counter.h lexer.h
to_compile := $(filter-out %.h, $(all_source))
$(findstring string,text)
Example:
find-tree:
# PWD = $(PWD)
# $(findstring /test/book/admin,$(PWD))
# $(findstring /test/book/bin,$(PWD))
# $(findstring /test/book/out,$(PWD))
$(subst search-string,replace-string,text)
This is a simple, nonwildcard, search and replace.
Example:
sources := count_words.c counter.c lexer.c
objects := $(subst .c,.o, $(sources))
$(patsubst search-pattern,replace-pattern,text)
This is the wildcard version of search and replace.
strip-trailing-slash = $(patsubst %/,%,$(directory-path))
The syntax of a substitution reference is:
$(variable:search=replace)
$(words text)
This returns the number of words in text.
Example: CURRENT_PATH := $(subst /, ,$(HOME))
words:
@echo My HOME path has $(words $(CURRENT_PATH)) directories.
$(word n,text)
This returns the nth word in text.
current := $(word $(words $(MAKEFILE_LIST)), $(MAKEFILE_LIST))
$(firstword text)
version_list := $(subst ., ,$(MAKE_VERSION))
major_version := $(firstword $(version_list))
$(wordlist start,end,text) :This returns the words in text from start to end,
inclusive.
$(sort list)
The sort function sorts its list argument and removes duplicates.
$(shell command)
stdout := $(shell echo normal message)
stderr := $(shell echo error message 1>&2)
shell-value:
# $(stdout)
# $(stderr)
Filename Functions
$(wildcard pattern...) :accepts a list of patterns and performs expansion
on each one.
sources := $(wildcard *.c *.h)
dot-emacs-exists := $(wildcard ~/.emacs)
$(dir list...): returns the directory portion of each word in list. If the file
name contains no slash, the directory part is the string `./'.
$(dir src/foo.c hacks) produces the result `src/ ./'
source-dirs := $(sort \
$(dir \
$(shell find . -name '*.c')))
$(notdir name...): returns the filename portion of a file path.
$(OUT)/myfile.out: $(SRC)/source1.in $(SRC)/source2.in
cd $(dir $@); \
generate-myfile $^ > $(notdir $@)
$(suffix name...): returns the suffix of each word in its argument.
# $(call same-suffix, file-list)
same-suffix = $(filter 1 $(words $(sort $(suffix $1))))
$(basename name...): returns the filename without its suffix.
$(basename src/foo.c src-1.0/bar hacks) produces src/foo src-1.0/bar
hacks.
$(addsuffix suffix,name...): appends the given suffix text to each word in
name.
$(addsuffix .c,foo bar) produces the result `foo.c bar.c'.
$(addprefix prefix,name...): complement of addsuffix.
$(addprefix src/,foo bar) produces the result `src/foo src/bar'.
$(join prefix-list,suffix-list):
$(join a b,.c .o) produces `a.c b.o'
Flow Control
$(if condition,then-part,else-part)
$(if $(filter $(MAKE_VERSION),3.80),,\
$(error This makefile requires GNU make version 3.80.))
$(error text): used for printing fatal error messages. After the function prints
its message, make terminates with an exit status of 2.
$(foreach variable,list,body)
Example:
letters := $(foreach letter,a b c d,$(letter))
show-words:
# letters has $(words $(letters)) words: '$(letters)'
$ make
# letters has 4 words: 'a b c d'
$(strip text): removes all leading and trailing whitespace from text and
replaces all internal whitespace with a single space.
$(origin variable): returns a string describing the origin of a variable.
The possible return values of origin are:
undefined,default,environment,environmentoverride,file,commandline,ov
erride,automatic.
$(warning text): The warning function is similar to the error function
except that it does not cause make to exit.
Example:
$(if $(wildcard $(JAVAC)),, \
$(warning The java compiler variable, JAVAC ($(JAVAC)), \
is not properly set.))
$(eval )

$(call macro-name[, param1...])


Thank You

You might also like