Thu 26 Jan 2017

Build Systems

Build systems don't usually deal with configuration.


Don't try to be clever and abstract things

Break everything into really small steps.

Make uses timestamps to work out when files are out of date.

Automatic Variables

$@ is the target.

$^ is all the dependencies.

The other automatic variables tend to make your makefile unreadable.


When unzipping things, you may need to touch the result. Alternatively, tell zip not to restore the dates.


Tup uses hashes to work out when files are out of date.

Tup removes files belonging to out of date targets.

tup graph and tup todo show useful information.


Tup supports make style variables with $(var).

Tup files

Syntax is:

# Comments

.gitignore # Generate a .gitignore for all my outputs.

input1.txt input2.txt |> ^flags run-some-command % |> output1.txt output2.txt {bin}

foreach input1.txt input2.txt |> ^flags run-some-command-on-each-file %f |> output1.txt output2.txt

Bins are a way to group outputs for use in the inputs to other

  • Flags
    • %f : input file paths
    • %b : input file basenames
    • %B : input file basenames without extensions
    • %o : output file paths
    • %O : output file paths without extensions
    • %g : string that a glob matches


This is a config file which follows a standard ini file format.


Run tup monitor or tup stop.

Only works on Linux.

The Paper

Build System Rules and Abstractions

Recursive make is bad, as we know.

But, operating on the whole dependency graph at once is slow. Each time we run make, we have to check every dependency in the graph to see if changed.

We can do better by asking the file system to tell us about changes, then looking up their dependencies and marking them as dirty.