Rules like this:
target: [prerequisite] [...] shell command another shell \ command on multiple lines
The target is the name of a file that can be built by those shell commands. If you run
make target and the target is older than any of the prerequisite files, or doesn't exist, Make runs the shell commands. The prerequisites are also file names; Make will look for rules to build them too, recursively. If all of them are up to date, Make will say `target' is up to date and exit without running any commands.
Some things that might trip you up at first:
Those shell commands must be indented by a proper tab character.
Each line of shell commands is $-expanded by Make before being passed to the shell. Make expands
$NAMEwould work like
Each logical shell command is run in a separate shell. The example above would result in something like the following:
$(SHELL) -c 'shell command' &&
$(SHELL) -c 'another shell command on multiple lines'
This means that shell variables and functions are not passed from one
command to the next.
Execution stops at the first failure.
If the symbols in a Makefile look weird, check the GNU
make Quick Reference. For convenience here are a few that are more common:
|Symbol||What it means|
||The file name of the target.|
||The name of the first prerequisite.|
||The names of all the prerequisites.|
||The directory part of
||The file-within-directory (
||A literal dollar sign. Useful when you really need to reference a shell variable.|
Make also has variables, recipes, functions, and conditional evaluation, for example, but everything is based around rules like the one at the top. Check out the GNU
make manual to learn more. There are other variants of Make, but GNU
make seems to be prevalent. Its manual calls out where behaviour is specific to GNU so it's a decent starting point for whatever variant you're working with.