Вы находитесь на странице: 1из 40

GNU Make

1-Mar-12
Enabling
the ARM Learning in INDIA

Objective
Most of the project requires the source code to be
distributed among many files. Modifications in any
one file necessitates compiling all the files. This will
be tedious and time consuming operation.
The make utility in Unix OS automates such tasks of
generating the object modules and the executables.
The make compiles only those source codes that are
modified and links with other object modules.
This session gives an insight into make utility.
Participants will look into the constituents of makefile.
After this session, participants can automate their
compiling requirements using the make utility.
1-Mar-12
Enabling
the ARM Learning in INDIA

GNU Make
Course outline

writing make rules


usingg macros/variables
/
taking advantage of implicit rules
using shell inside make files
dealing with sources spread across directories

1-Mar-12
Enabling
the ARM Learning in INDIA

About make

A utility that determines dependencies in creation of targets

Builds files that are out of date

Not specific to any language

Traditionally been used on UNIX platform

Various ports exist

GNU - GNU make

Microsoft - nmake

1-Mar-12
Enabling
the ARM Learning in INDIA

Building an application manual way


$ gcc -c foo1.c

foo

foo1.o

foo1.c

foo1.h

$ gcc -c foo2.c
$ gcc -o foo foo1.o
foo2.o

foo2.o

foo2.c

1-Mar-12
Enabling
the ARM Learning in INDIA

foo2.h

Simple make file


$ cat makefile

foo

foo1.o

foo1.c

foo1.h

ffoo: foo1.o
f 1
foo2.o
f 2
gcc -o foo foo1.o

foo2.o

foo2.c

foo2.h

foo2.o: foo2.c foo2.h


gcc -c foo2.c
foo1.o: foo1.c foo1.h
gcc -c foo1.c

Enabling the ARM Learning in INDIA

foo2.o
foo1.h

How to run make


$ make
reads and processes makefile in the current
directory
directory,
$ make [-f mymake] [target]
reads and processes mymake in the current
directory,
Enabling
the ARM Learning in INDIA
1-Mar-12

Alternate Ways
Normal compilation of a
sample application
$ gcc -o sample sample.c

What if we had included


sample.h in sample.c ?
Revised makefile

Doing it with make


$ make
Contents of makefile
1-Mar-12
sample
: sample.c
gcc -o sample sample.c

sample : sample.c sample.h


gcc -o sample sample.c
Is the following valid as well?
sample : sample.h sample.c
gcc -o sample sample.c

Enabling the ARM Learning in INDIA

Comments
sample make to illustrate how to use comments
# rule to generate foo2.o object file
foo2.o : foo2.c foo2.h foo1.h
gcc -cc foo2.c

# compile
compile-only
only

using # not as comment indicator


HASH = \#
BACKSLASH =\\
run:
echo HASH is $(HASH)
echo BACKSLASH is $(BACKSLASH)
Enabling the ARM Learning in INDIA

Constituents of a make file


Rules
Variables
Directives
Inclusion of another make
Conditional directives

Comments
Text that follows # symbol is treated as
comment
To include # literally, prefix with \
1-Mar-12
Enabling
the ARM Learning in INDIA

Rules
Syntax

target1 [target2] : [prerequisite1] [prerequisite2 ]


<TAB>command-1
<TAB>command-2
...

C
Components
t
Targets
File names

dependency

target

sample : sample.c
gcc -o sample sample.c
Dependencies/ prerequisites rule
Commands
Action names

Compilation / linking
Any other command
1-Mar-12
Enabling
the ARM Learning in INDIA

command

Rules
Explicit rule
explicitly specify the prerequisites for a specific
target

Implicit rules
Take advantage of the knowledge make has about
known patterns of files (e.g., .c, .cpp .o, .s )
Further classified into pattern rules & suffix rules
Enabling the ARM Learning in INDIA

Processing of make file


Two-phase processing
Phase-1
Read include files, if any
Expand variables and functions
Process conditional directives
Construct dependency graph

Phase-2
Determine which targets to be rebuild
Invoke necessary rules
1-Mar-12
Enabling
the ARM Learning in INDIA

Processing of make file


Immediate expansion
Expansion that happens during the first phase

Deferred
Expansion
i that
h d
does not h
happen d
during
i the
h fi
first phase
h
immediate

immediate

targets : dependencies
actions (or commands)

deferred
1-Mar-12
Enabling
the ARM Learning in INDIA

Multiple rules in a make file


target1 :
echo processing rule 1

t
target2
t2 :

$ make target3
echo processing rule 3
processing rule 3

echo processing rule 2

target3 :
echo processing rule 3

$ make target1 target3


echo processing rule 1
processing rule 1
echo processing rule 3
processing rule 3

Enabling the ARM Learning in INDIA

Prefixes to commands
Prefix

Action

- ignore command errors,


if any

TARGET1 = $(SRC_DIR)
SRC_DIR = proj/src
TARGET4 := $(SRC_DIR)
show:
+@echo this message is always

@
to

dont echo the command

show
@echo TARGET1 is $(TARGET1)

standard output

-rm *.o
rm *.o

+ execute the command even if


n option is selected
Enabling the ARM Learning in INDIA

-rm *.o

Predefined Variables
Some commonly used variables predefined by GNU make CC
, FLAGS , CFLAGS, LDFLAGS
foo foo1.o
foo:
foo1 o foo2.o
foo2 o
gcc -o $@ $^

CC = gcc
foo : foo1.o

foo2.o

foo2.o : foo2.c foo2.h foo1.h

foo2.o: foo2.c foo2.h foo1.h


gcc -c $<
foo1.o: foo1.c foo1.h
gcc -c $<

Enabling the ARM Learning in INDIA

foo1.o :foo1.c foo1.h

user defined variables


Simple variable
Defined using the :=
assignment
g
operator
p
Right-hand side is expanded
immediately, and result
assigned to the variable
Any undefined variable
referenced on the right-hand
side expands to nothing
Enabling the ARM Learning in INDIA

$(variable) is to reference a
variable

SRC_DIR := proj/src
TARGET_DIR := $(SRC_DIR)
show:
echo $(TARGET_DIR)

user defined variables


Recursive variable
Defined using the =
assignment operator
Right-hand side is stored
as a value of the variable
Expansion done each
time the variable is used

TARGET1 = $(SRC_DIR)
TARGET2 := $(SRC_DIR)
SRC_DIR = proj/src
TARGET3 = $(SRC_DIR)
TARGET4 := $(SRC_DIR)
show:
echo TARGET1 is $(TARGET1)
echo TARGET2 is $(TARGET2)
echo TARGET3 is $(TARGET3)
echo TARGET4 is $(TARGET4)

Enabling the ARM Learning in INDIA

Automatic variables

foo: foo1.o foo2.o


gcc -o foo foo1.o foo2.o

foo: foo1.o foo2.o

foo2.o: foo2.c foo2.h foo1.h


gcc -c foo2.c
f 2

foo2 o: foo2.c
foo2.o:
foo2 c foo2.h
foo2 h foo1.h
foo1 h

gcc -o $@ $^

gcc -c $<

foo1.o: foo1.c foo1.h


gcc -c foo1.c

$@

foo1.o: foo1.c foo1.h


gcc -c $<

name of the target


$<

name of the first prerequisite

$^

names of all prerequisites

Enabling the ARM Learning in INDIA

other types of assignments


Conditional assignment
Defined using the ?= operator
Value assigned only if variable has not been defined yet
ARCH ?= x86

Append operator
Defined using the += operator
Append right side of the text to the variables content
Applicable for simple variables
SRC += x.c
Enabling the ARM Learning in INDIA

variables
Variables can be defined or
redefined from command line
$ make
$ make VAR1=abc VAR2=xyz
Use override directive to let
undesirable command line
redefines for a variable be
ignored
1-Mar-12
Enabling
the ARM Learning in INDIA

VAR1=dummy
VAR2=
all:
echo VAR1 = $(VAR1)
echo VAR2 = $(VAR2)

override VAR1=dummy

Wildcards
GNU make supports
*

? ~

[]

foo: foo1.o foo2.o


gcc -o $@ $^
foo2.o: foo2.c foo2.h foo1.h
gcc -c $<
foo1.o: foo1.c foo1.h
gcc -c $<
1-Mar-12
Enabling
the ARM Learning in INDIA

Does this
work always?

[^]
foo: *.o
gcc -o $@ $^

foo2.o: foo2.c foo2.h foo1.h


gcc -c $<
foo1.o: foo1.c foo1.h
gcc -c $<

functions
General syntax
$(function-name arg1[,argn])

SRC := x.c
x c y.c
y c z.c
zc
String functions
$(subst search-str,replace-str,text)
OBJS := $(subst .c,.o,$(SRC))

$(patsubst search-pat,replace-pat,text)
OBJS := $(patsubst %.c, obj/%.o, x.c y.c z.c)
Enabling the ARM Learning in INDIA

functions
Warning function
Very useful for debugging
Can be placed anywhere in a makefile
$(warning TARGET not defined)
outputs in the format
<filename>:<linenum>:TARGET not defined

Shell function
Can be used to invoke any external program
today := $(shell date)
Enabling the ARM Learning in INDIA

Wildcards
foo: *.o
gcc -o $@ $^
foo2.o: foo2.c foo2.h foo1.h
gcc -c $<
foo1.o: foo1.c foo1.h
gcc -c $<

SRCS := $(wildcard *.c)


OBJS := $(subst .c,.o,$(SRCS))
foo: $(OBJS)
gcc -o $@ $^
foo2.o: foo2.c foo2.h foo1.h
gcc -c $<
foo1.o: foo1.c foo1.h
gcc -c $<

Enabling the ARM Learning in INDIA

pattern rule
Specifies rules on how
specific targets have to be
created
File pattern contain %
character
target_pat : dep-pat
commands

%.o : %.cpp
g++ c $<

Enabling the ARM Learning in INDIA

foo : foo1.o

foo2.o

g++ -o $@ $
$^
foo2.o: foo2.h

foo1.h

foo1.o: foo1.h
# pattern rule for .cpp to .o
%.o : %.cpp
g++ -c $<

Implicit rules
Built in pattern rule exist for C, C++, FORTRAN, Pascal, assembler
No built-in rules for some languages, e.g., Java & XML
Example (built-in implicit rule)

%.o:%.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
where
COMPILE.c =$(CC) $(CFLAGS) $(CPPFLAGS ) $(TARGET_ARCH) -c
CC =cc
OUTPUT_OPTION =-o $@
Enabling the ARM Learning in INDIA

Implicit rules
Applied when no explicit rule to update target exists
Uses the implicit rule data base
Implicit rules are defined using pattern rule
%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
OUTPUT_OPTION = -o $@

An implicit rule without a command deletes the rule


Enabling the ARM Learning in INDIA

Implicit rules
foo : foo1.o foo2.o
gcc -o $@ $
$^
foo2.o : foo2.c foo2.h foo1.h
gcc -c $<
foo1.o : foo1.c foo1.h
gcc -c $<

Enabling the ARM Learning in INDIA

# taking advantage
# of implicit rules
foo: foo1.o

foo2.o

gcc -o $@ $^
foo2.o: foo2.h
foo1.o: foo1.h

foo1.h

Rules without commands


OPTIONS = -c
CC = gcc
all: foo
foo: foo1.o

foo2.o

gcc -o $@ $^
foo2.o: foo2.h

foo1.h

foo1.o: foo1.h

foo1.o: foo1.c foo1.h


$(CC) $(OPTIONS) foo1.c
foo2.o: foo2.c foo2.h
$(CC) $(OPTIONS) foo2.c
foo: foo1.o foo2.o
$(CC) foo1.o foo2.o

Enabling the ARM Learning in INDIA

Cleaning up intermediates
Some complex operations leave a number of
intermediate object files or temporary files
Provide target clean for necessary cleanup

To perform clean
$ make clean
To perform rebuild
$ make rebuild

clean:
-rm *.o

clean:
-rm *.o
rebuild: clean foo

Enabling the ARM Learning in INDIA

PHONY targets
Phony target
Identified by .PHONY target modifier
not a real target file name
no undesired effect even if a file with the
target name exists
Prerequisites are optional
To perform clean
$ make clean
Enabling the ARM Learning in INDIA

.PHONY: clean
clean:
-rm *.o

conditionals
conditional-directive
text-if-true

Conditional directives

endif

ifeq
ifneq
conditional-directive
text-if-true
else
text-if-false
endif

Enabling the ARM Learning in INDIA

ifdef variable-name
ifndef variable-name

Include directive
include filename
Causes specified
p
make
file(s) to be included
Contents of config.mk
CC = gcc
CFLAGS = -O2
CPPFLAGS = -I$(HOME)/proj/inc
Enabling the ARM Learning in INDIA

Contents of makefile
include config.mk
foo : foo1.o foo2.o
$(CC) -o $@ $<
foo1.o : foo1.c

foo1.h

foo2.o : foo2.c foo2.h foo1.h

Project with multiple sub-directories


module.mk

make file in mod1 directory

DIR = mod1
SRC += $(
$(DIR)/main.c
)/
$(DIR)/main.o : $(DIR)/main.c $(DIR)/main.h
module.mk

make file in mod2 directory

DIR = mod2
SRC += $(DIR)/dummy.c
$(DIR)/dummy.o : $(DIR)/dummy.c $(DIR)/dummy.h
Enabling the ARM Learning in INDIA

proj
|
|---mod1
| |
| |--main.c
| |
| |--main.h
|
|---mod2
| |
| |--dummy.c
| |
| |--dummy.h
|

Project with multiple sub-directories


makefile

make file in proj directory

MODULES := mod1 mod2


CFLAGS += $(patsubst %,
% -I%
I%,$(MODULES))
$(MODULES))
SRC :=
all: prog
include $(patsubst %,%/module.mk,$(MODULES))
OBJ := $(patsubst %.c,%.o, $(SRC))
prog: $(OBJ)
$(CC) -o $@ $(OBJ)

Enabling the ARM Learning in INDIA

proj
|
|---mod1
| |
| |--main.c
| |
| |--main.h
|
|---mod2
| |
| |--dummy.c
| |
| |--dummy.h
|

common errors
Using spaces as prefix for commands.
Prefixing a comment with TAB character
Missing target name
While specifying dependencies placing .h file
names before .c file names
Enabling the ARM Learning in INDIA

GNU Make command options


Option

action

-f file

use file as the makefile

-n

print commands that would be executed but


no actual execution

-s

silent mode (do not print commands as they


are executed)

-t

touch files (set modification time stamp to current)

-v

print version of make

-p

print database used by make

-d

print debug info

1-Mar-12
Enabling
the ARM Learning in INDIA

References
Managing Projects with GNU Make, Robert
Mecklenburg, OReilly, 2005 (Indian Ed.)
www.gnu.org/software/make/manual
Linux Programming Bible John Goerzen (Chapter
7)
Recursive make considered harmful Peter Miller
Enabling the ARM Learning in INDIA

Вам также может понравиться