Make (build tool)

Check proper tab usage: “cat -e -t -v Makefile” - tab inferno

see also

Your Makefiles are wrong - Your Makefiles are full of tabs and errors. An opinionated approach to writing (GNU) Makefiles that I learned from Ben may still be able to salvage them.

The big things I hope you take away are:

  • The file system is a fundamental part of Make, don’t fight it
  • Use sentinel files for targets that do not yield exactly one file
  • Don’t use tabs, set -ea -o pipefail, and a few other sensible defaults
  • Use the above as guidelines, not dogma

Make (1976)

First tool to allows to break build operation in 2 parts:

  • a set of task, and dependencies between them
  • a set of recipes to execute the task

Make concept had give birth to a lot tools, trying to improve it or extends it in some ways.

CFLAGS ?= -g

all: helloworld

helloworld: helloworld.o
	# Commands start with TAB not spaces
	$(CC) $(LDFLAGS) -o $@ $^

helloworld.o: helloworld.c
	$(CC) $(CFLAGS) -c -o $@ $<

clean: FRC
	rm -f helloworld helloworld.o

Done at a time were library or module were fewer than now. Use of shell one line for building recipes give some flexibility, but does not scale well to when operation becames more complex (this was latter adressed by tool like CMake).

Recursive build description for package of package, was an issue.

Mixing description of build inside the build, make them non portable (when moving to an other compiler for ex).

Pros:

  • very simple concept and low learning curve
  • easy to customize and versatile
  • available everywhere on UNIX

Cons:

  • tab format (bite everyone)
  • shell limit: in term of expression and execution:
    • one shell process instanciated by row
    • no possibility of sharing state except using file.

I keep looking for a more modern replacement

Make is really a complicated combination of these components:

  • a dependency definition language with in-place evaluation and half-assed wildcards

  • A functional language with extremely limited datatypes (effectively just space-separated strings)

  • a clunky macro system

  • A “distributed” topological execution engine (did you know Make can coordinate job slots across recursive executions of Make? It’s impressive! And shouldn’t have to exist!) 1

All the alternative build systems wisely choose to tackle only some of these features.

The most interesting development in this space is the paper “Build Systems A La Carte” 2 by Mokhov, Mitchell, & Peyton Jones, who did a great job of breaking down build systems to their fundamental concepts, and along the way found one particular point of the design space that wasn’t fulfilled (Table 2, p79:16).

Written on December 8, 2018, Last update on April 28, 2024
build-system