← ppnm

Make utility

In POSIX systems "make" is a utility to manage pojects on a computer (programs, libraries, articles, reports, web-sites, and others) where files must be manipulated according to certain rules.

When make is run, it reads the description of the project from a makefile (normally called Makefile or makefile) and then automatically updates the project, if necessary, according to the rules in the makefile.

Makefile

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 resembles a cookbook and consists of macro definitions and rules.

Macro definitions

A macro definition looks like a normal assignment in a programming language, for example
MCS = mcs -optimize+ -platform:arm
The macro can then be called as $(MCS) and will return the string "mcs -optimize+ -platform:arm".

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 written 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 target 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
One can also build a specific target, say 'test', with the command
make test
Hint: bash-completion feature actually works on the targets in the current Makefile.

'Hello world' example

Suppose we have a project to create a file "Out.txt" with the text "hello world" using a hello-world C#-program wholly contained in the file "hello.cs".

The makefile for the project could look like this,

Out.txt : hello.exe         # Out.txt depends on bytecode executable hello.exe
	mono hello.exe > Out.txt  # run hello.exe in mono, redirect output into Out.txt

hello.exe : hello.cs           # bytecode hello.exe depends on source-code hello.cs
	mcs -out:hello.exe hello.cs   # compile hello.cs, output goes to hello.exe

.PHONEY:clean           # clean is a phoney target
clean:                  # does not depend on anything
	rm --force Out.txt hello.exe # remove the files produced by making
Comments start with the hash-sign, #.