What's in a Makefile?

allenap profile image Gavin Panella ・2 min read

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 $(NAME) and ${NAME} but $NAME would work like ${N}AME.

  • 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.
$(@D) The directory part of $@.
$(@F) The file-within-directory (basename) part of $@.
$$ 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.

Good luck!


Editor guide