Note "make"

make

make is a utility to manage pojects in a computer: programs, libraries, articles, reports, web-sites and other projects.

When make is run, it reads the description of the project from a makefile and then automatically updates the project, if necessary, according to the description in the makefile.

Makefile

A makefile contains a description of the project in the declarative makefile language. By default a makefile must have the name Makefile or makefile. If the makefile is called SomethingElse then the make utility must be called as

make -f SomethingElse.

A makefile consists of macro definitions and rules and resembles a cookbook.

Macro definitions

A macro definition looks like a normal assignment in a programming language,
CFLAGS = -Wall -std=gnu99
The macro can be called as $(CFLAGS) and will return the string "-Wall -std=gnu99".

Rules

A rule looks very much like an instruction for preparing a dish. It has the following syntax,
dish : ingredients
recipe
where the sign denotes the (mostly invisible, unfortunately) tabulator-sign. Yes, by default a recipie starts with the tabulator-sign. This aspect has been a subject of critisism, so in the GNU-make version 3.82+ one can change the default tabulator-sign to any other sign—for example a semicolon ;—by defining a macro .RECIPEPREFIX := ;.

The rule is interpreted like the following:

The GNU-make manual uses a somewhat different notation,

target : prerequisites
recipe

If the recipie consists of one command only, it can be writte in the same line as the target,

target : prerequisites ; recipe

By default 'make' only builds the first target it finds in the makefile. Therefore if more than one targets must be built one makes a "phoney" target that depends on the targets that must be built by default,

.PHONEY: default
default : target1 target2 target3

'Hello world' example

Suppose we have a project to create a file out.txt with the text "hello world" in it using a 'hello world' c-program.

The makefile for the project could look like this,

out.txt : hello         # out.txt depends on hello
./hello > out.txt     # this is how you make out.txt from hello

hello : hello.o         # hello depends on hello.o
cc hello.o -o hello   # this is how you make hello from hello.o

hello.o : hello.c       # hello.o depends on hello.c
cc -c hello.c         # this is how you make hello.o from hello.c

.PHONEY:clean
clean:                  # this is "clean" target it does not depend on anything
rm -f out.txt hello hello.o
where the hash-sign # signifies the beginning of a comment.