GNU Make Manual

Table of Contents

Makefile

The file name can be one of GNUmakefile, makefile and Makefile, but Makefile is mostly recommended.

Include

Evaluation

immediate = deferred
immediate ?= deferred
immediate := immediate
immediate ::= immediate
immediate += deferred or immediate
immediate != immediate

immediate : immediate ; deferred
        deferred
immediate
Expanded during when Makefile is parsed, included, etc.
deferred
Expanded during when other expanding rule requires it or actual invoking(target-update)

You can take advantage of .SECONDEXPANSION special rule and $$ to defer expanding some prerequisites:

.SECONDEXPANSION:
AVAR = top
onefile: $(AVAR)   # top
twofile: $$(AVAR)  # bottom
AVAR = bottom
.SECONDEXPANSION:
main_OBJS := main.o try.o test.o

main: $$($$@_OBJS)

# After the first phase:
#   $($@_OBJS) 
# During the second phase:
#   $(main_OBJS) =>
#   main.o try.o test.o

Wildcard

Parallel Execution

To force some targets to run parallel:

foo:
  $(MAKE) --jobs 'bar' 'baz'
bar:
  echo 'bar'
baz:
  echo 'baz'

Recursive Use of make

subsystem:
        $(MAKE) -C subdir

Rules

target … : prerequisites …
        recipe

target

usually the name of a file, can also be the name of an action (Phony Targets)

Phony Targets
Not refer a file but just the name of an action. They are not prerequisites of something, or does not require some other prerequisites
prerequisite

the names of files that the target depends on

recipe

must be indented with \t, or set .RECIPEPREFIX to your taste

When execute the command make <target>:

  1. Reads the Makefile in the currenty directory
  2. Pick <target>'s rule or the first rule if <target> is omitted
  3. Process the rule recursively:
    1. Process the rule's prerequisites
    2. Run its own recipe if some of its prerequisites are newer than its own target.

Multiple Rules for One Target

Static Pattern Rules

objects = foo.o bar.o

all: $(objects)

$(objects): %.o: %.c
        $(CC) -c $(CFLAGS) $< -o $@

Implicit Rules

x: y.o z.o

when x.c, y.c and z.c all exist will execute:

cc -c x.c -o x.o
cc -c y.c -o y.o
cc -c z.c -o z.o
cc x.o y.o z.o -o x
rm -f x.o
rm -f y.o
rm -f z.o

Pattern Rules

# Specifies how to make a file n.o, with another file n.c as its prerequisite,
# provided that n.c exists or can be made.
%.o : %.c ; recipe…

Double Colon Rules

Targets

Phony Targets

.PHONY: clean
clean:
        rm *.o temp
SUBDIRS = foo bar baz

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

$(SUBDIRS):
        $(MAKE) -C $@

foo: baz

Prerequisites

Normal
Just a usual thing
Order-only
Placed after |, just specify the dependency, but not triggers the target even if it's newer.
a: b
    touch a
b: c
    touch b
c:
    touch c
x: | y
    touch x
y: | z
    touch y
z:
    touch z
$ make a
touch c
touch b
touch a
$ make x
touch z
touch y
touch x
$ make a
make: `a' is up to date.
$ make x
make: `x' is up to date.
$ touch c
$ make a
touch b
touch a
$ touch z
$ make x
make: `x' is up to date.
$ rm c
$ make a
touch c
touch b
touch a
$ rm z
$ make x
touch z

VPATH

# 'src' and '../headers' are searched for all prerequisites
VPATH = src:../headers
vpath %.c foo
vpath %   blish
vpath %.c bar

vpath %.c # clear out for %.c
vpath     # clear out for all

Recipes

Echoing

@echo About to make distribution files

Shell for Recipe

Errors in Recipes

clean:
        -rm -f *.o

Canned Recipes

When the same sequence of commands is useful in making various targets:

define run-yacc =
yacc $(firstword $^)
mv y.tab.c $@
endef

foo.c : foo.y
        $(run-yacc)

Variables

# recursively expanded variable
# -----------------------------
foo = $(bar)
bar = $(ugh)
ugh = Huh?

all:;echo $(foo)  # prints 'Huh?', by recursive expansion
# simply expanded variable
# ------------------------
# For GNU make, '::=' is equivalent to ':='
# POSIX standard only supports '::='

x := foo
y := $(x) bar  # evaluated right away
x := later

all:
  echo $(y)  # prints 'foo bar'
  echo $(x)  # prints 'later'
foo := a.o b.o c.o
bar := $(foo:.o=.c)    # substitution
bar := $(foo:%.o=%.c)  # same as above
# like setdefulat
FOO ?= bar  # set a value only if it’s not already set

# Equivalent to above
ifeq ($(origin FOO), undefined)
  FOO = bar
endif
$(origin variable)
tell the source of the variable, like undefined, environment, default, etc.
# Set the ouptut of a shell execution to the variable
hash != printf '\043'
file_list != find . -name '*.c'

# Equivalent to above
hash := $(shell printf '\043')
var := $(shell find . -name "*.c")
objects += another.o

# Equivalent to above
objects := $(objects) another.o
# Target specific variable, wil be inherited by dependent targets
prog : CFLAGS = -g
prog : prog.o foo.o bar.o

EXTRA_CFLAGS =

prog: private EXTRA_CFLAGS = -L/usr/local/lib  # not inherited
prog: a.o b.o

Conditionals

libs_for_gcc = -lgnu
normal_libs =

foo: $(objects)
ifeq ($(CC),gcc)
        $(CC) -o foo $(objects) $(libs_for_gcc)
else
        $(CC) -o foo $(objects) $(normal_libs)
endif

Functions

$(function arguments)

Define custom functions

define foo
echo $(1)
endef

bar:
    @$(call foo,'Hello World!')

CLI

Conventions