Introduction of Make

* Introduction

Building a program from source code typically involves a few common steps:

– Writing the source code

– Process the code to expand all *#include* files, macros, etc.

– Compiling the expanded source code to machine assembly language

– Compiling assembly language to machine  binary code

– Linking binary code in multiple files or libraries into

  an executable binary program

Executing these steps on a small set of source code may be manageable, but

as the source code gets larger, the  process becomes more complex.

* The Make System

The *make* command looks for a file called *Makefile* which

defines targets and their prerequisites, and the rules, or

recipes, used to create them.


all: myprog

myprog: myprog.o

gcc myprog.o -o myprog


gcc -c myprog.c


rm -f *.o myprog core


To build *myprog* with this *Makefile*:


make myprog


We could shorten it to just this:




** Rules, Targets, Dependencies

A /rule/ consists of a /target/, the files it depends on and the

actions required to build it.

A rule defines:

  – name of the target(s)

  – how to decide if the target is out of date and needs to be built

  – how to create or update the target

*Make* uses the modification times of the

dependencies to determine when the actions should be invoked.

The commands to build a target are executed if:

  – the target file does not exist

  – the modification time of the prerequisite(s) are newer than

    the existing target file

What happens if the target file exists but the prerequisites do not?

Execution lines must begin with a *<TAB>* character; spaces are not permitted.

Command lines can be continued with a backslash as the last character.

Each line is executed as a separate shell command and processed

by the command interpreter defined in the “SHELL” variable which

defaults to “/bin/sh”.

The exit status of each shell is examined by *make*.  If the shell

completed successfully (exit 0), then *make* continues its execution

with the next line. Otherwise, it exits.

The exit value of a line can be ignored by prefacing it with a *-*.



      -rm -f *.o a.out core


** Common Targets

Some common targets are *all* and *clean*.  The target *all* typically

builds all of the program targets of the *Makefile*.  The *clean*

target typically cleans up after the compiler to leave the build directory

in its pre-build state.  These are not required nor predefined, you must

define them, if desired.


all: mywc

mywc: mywc.o


        @rm -f *.o mywc a.out core


Normally, *make* will echo each line before executing it.  This can be

turned off with an /’@’/ at the beginning of the line.

** Multiple Targets in a Rule

If multiple targets are defined in a rule, *make* treats each as if it

is a separate target with identical prerequisites and commands.

This is useful to add a prerequisite or when similar recipes are used

for all targets.


king.o queen.o knight.o rook.o: moves.h


** Variables and Macros

*Make* uses variables extensively. Some variables are predefined by *make*.

Environment variables are inherited from the calling

program, and there can be user-defined variables.

Macros are used similarly to variables.


CC = gcc

OBJECTS = myprog.o

CFLAGS = -g -v

myprog = “myprog”

$(myprog): $(OBJECTS)

        $(CC) $(CFLAGS) $(OBJECTS) -o $@


Environment variables are inherited from the calling environment.

Every environment variable that *make* sees is turned into a *make*

variable with the same name and value.

An explicit variable assignment in a *Makefile* will override the


In order to prefer the inherited values, use the command-line

flag /-e/.

Environment variables are passed to rule command lines and

recursive *make* commands.

Variables can be added to the environment to make it available

to shell commands, or prevented from being exported:


export MYVAR1 MYVAR2

unexport GCC CFLAGS


The value of a variable can be appended after it is set:


SOURCEFILES = main.c printf.c




Some variables are defined automatically.

Automatic variables are evaluated fresh for each rule that is

executed, instead of having a fixed value. Some examples:

  – $@      Name of the target

  – $<      Name of the first prerequisite

  – $^      Names of all the prerequisites

  – $?      Names of all prerequisites which are newer than the target

A link to a table of automatic variables is included in the References.

** Suffix & Pattern Rules

By itself, *make* knows how to create a /.o/ file from

its corresponding /.c/ file. It has the following

rule based on filename suffixes predefined:



$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<


The rule may also be written as a /Pattern/ rule:


%.o: %.c

$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<


The /%/ represents the basename of the target file.  Note the use of

/variables/ to generalize the rule. The /$@/ is the current target and

the /$</ is the current dependency.

Similar to the implicit rule for /.o/ files, *make* has

a predefined implicit rule for making an executable

file from a /.c/ file.


$(LINK.c) -o $@ $< $(LDLIBS)


The rule uses a macro that is defined as:




Because of predefined macros and implicit rules, our previous example can

be shortened to this:


all: myprog



rm -f *.o myprog core


Implicit rules make used of many variables, such as:

   – AR           Program to make archive libraries; default *ar*

   – CC           Program for compiling C programs; default *cc*

   – CFLAGS       Extra flags for the C compiler

   – LDFLAGS      Extra flags for the linker

A link to a table of some common variables used by implicit rules

as part of the References.

** Directives

Several /directives/ are available to modify the behavior of *make*:

*** Conditonal Directives

/Conditional/ directive causes parts of the *Makefile* to be used or ignored

based on the value of variables:

  – ifeq /( arg1 , arg2 )/

  – ifneq /( arg1 , arg2 )/

  – ifdef /condition/

  – ifndef /condition/

  – else

  – endif

*** Other Directives

The *include* directive causes *make* to read the specified file(s)

before continuing.  The *override* directive changes the value of a

variable which was set on the *make* command line:

  – include /file1/ /file2/ /…/

  – override /var = value/

** Recursive *make*

The *make* command can be used in a *Makefile* just as any other

command.  This is useful when there are multiple susbsystems which

comprise one larger system:


subdir = /some/other/dirname


        $(MAKE) -C $(subdir)


Environment variables are passed to each command line and recursive *make*.

By default, only environment variables that came from the environment or the

*make* command line will be passed. The /export/ directive can pass other


What happens in the following example?


FOO = foo


      echo $$FOO


** Command Line Arguments

*Make* has many command line arguments which can alter its behavior.

Variables can be set on the command line.

Some common arguments:

  – make -i          /# Ignore the exit value of shell commands/

  – make -d          /# Print debugging information/

  – make -n          /# Dry-run; only print what would be done/

  – make -t          /# Touch files instead of running rules/

  – make -e          /# Environment variables override *Makefile* assignments/

  – make -r          /# Disable the built-in implicit rules/

  – make -j /N/        /# Run N jobs at once/

  – make VAR=value   /# Set the value of variable VAR/

** Further Exploration

Most GNU source code (and many others) use

*autoconf* and *automake* to create templates for *make*

which make it more portable and can better account for the

build machine environment.  These are commands that make


* Make Tutorials Available on the Web

** A Simple Makefile Tutorial:


** Tutorial by Example:


** A tutorial and reference *PDF*:


* Make References

** The GNU *make* reference manual:


** Catalogue of Built-In Rules


** Default Suffix Rules and Predefined Macros


** List of Automatic Variables


** Variables Used by Implicit Rules


** A Short Guide to Makefiles:


** A GNU *make* cheat sheet on /GitHub/

   Includes a *Makefile* for building a PDF version from LaTex source files:


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s