1 of 23

Make: Build Software

Alexius Wadell

Lover of Make and all Directed Acyclic Graphs

1

1

1

1

2 of 23

Build Tools: Automating Compilation

Blaze Inspired

Makefile Generation

Other Tools

2

2

2

2

3 of 23

Why Make?

Pros

  1. Lightweight
  2. Recipes are shell scripts
  3. It’s just makefiles

Cons

  1. Non-Hermetic
  2. Uses timestamps
  3. No caching of artifacts

3

3

3

3

4 of 23

But I don’t compile code…

Do you?

  • Download compressed files and then unzip them
  • Generate result files by running scripts
  • Run tests that depend on input files
  • Install dependencies with pip, conda, Pkg.jl, spack

4

4

4

4

5 of 23

Let’s Make Pie!

Target

Prerequisites

Rule

Recipe

5

5

5

5

6 of 23

Let’s Make Pie!

6

6

6

6

7 of 23

What’s going on?

  1. Build a DAG to represent dependencies
  2. Check that we have needed files
  3. Identify missing files
  4. Use recipes to build missing files

butter

pie_crust

flour

libbys_pumpkin

pumpkin_filling

pumpkin_pie

salt

water

7

7

7

7

8 of 23

Summarizing Data

8

8

8

8

9 of 23

Automatic Variables

Symbol

Use

$@

Filename of the target

$<

Filename of 1st prerequisites

$(@D)

The directory of the target

9

9

9

9

10 of 23

Phony Targets

With no arguments, make builds the first target it finds

  • So far that’s what we’ve wanted
  • But can be undesirable for larger projects

Ever seen something like:

  • make build
  • make install
  • make clean
  • make test

10

10

10

10

11 of 23

Phony Targets

Define targets that are not files

  • Avoids conflicts existing filenames
  • Indicates to make that this rule doesn’t create a file

Some uses

  • Submitting jobs to slurm
  • Download all data files
  • Deleting generated files

11

11

11

11

12 of 23

Pattern Rules: Transform Files by Name

12

12

12

12

13 of 23

Chaining Rules

all

data1.csv

data1.sum

grand.csv

data2.csv

data2.sum

grand.sum

sum.py

13

13

13

13

14 of 23

Multi-Target Pattern Rules

all

data1.csv

data1.sum

grand2.csv

data2.avg

data2.csv

grand2.avg

sum_avg.py

14

14

14

14

15 of 23

Programs without Output

Not all programs produce “output”

  • pip install package
  • spack install package

Possible Solutions

  • Have an install rule and run manually
  • Have an install rule and depend on it

15

15

15

15

16 of 23

Enter the Witness File

16

16

16

16

17 of 23

Next Steps

17

17

17

17

18 of 23

Homework

  • Work through the example exercises
  • Clone Julia and build it from scratch: https://github.com/JuliaLang/julia
  • Add a makefile to your repo (Last week’s homework) that:
    • Installs any dependencies with “make install”
    • Runs a test suite with “make test”

18

18

18

18

19 of 23

Resources

Documentation

Make in the Wild

19

19

19

19

20 of 23

Common Gotchas

20

20

20

20

21 of 23

Common Gotchas

Never use make –j to submit jobs to slurm or any other scheduler

Formatting:

  • Recipes are indented with 1 tab character (Not spaces)
  • Make is whitespace sensitive: Don’t put whitespace in filenames
  • Turn on “show whitespace” in your editor

Shell:

  • Each line in a recipe is executed in it’s own shell
  • Setting variables on one line and using later doesn’t work!
  • Adding “.ONESHELL:” to your makefile will run recipes in a single shell

21

21

21

21

22 of 23

Common Gotchas: Path Handling

Directories time stamps are not updated when contents change

  • Always touch directories after modify, if using as a target
  • Ideally track files at the file level, not the directory

Make matches on strings not canonical filenames

  • Recommend including trailing “/” in directory names
  • “apple//bar/foo” and “apple/bar/foo” are the same to POSTX, but not make
  • Avoid spaces in filenames (Including parent paths)

22

22

22

22

23 of 23

Common Gotchas: Limitations

Make is not hermetic

  • It is sensitive to your path (is “python” python 2 or 3?)
  • External changes (pip uninstall…) can mess up your build
  • bazel is hermetic, but it is a lot more work for non-standard workflows

Recursive Make Considered Harmful

  • tldr: Don’t call make from within make. Just don’t.
  • No guarantee that it will terminate

23

23

23

23