I learned to use the command line utility make
in the context of building C programs. The program make
reads an input file to tell it how to make things. To make a C program, you compile the source files into object files, then link the object files together.
You can tell make
what depends on what, so it will not do any unnecessary work. If you tell it that a file foo.o
depends on a file foo.c
, then it will rebuild foo.o
if that file is older than the file foo.c
that it depends on. Looking at file timestamps allows make
to save time by not doing unnecessary work. It also makes it easier to dictate what order things need to be done in.
There is nothing about make
that is limited to compiling programs. It simply orchestrates commands in a declarative way. Because you state what the dependencies are, but let it figure if and when each needs to be run, a makefile is more like a Prolog program than a Python script.
I have a client that needs a dozen customized reports, each of which requires a few steps to create, and the order of the steps is important. I created the reports by hand. Then, of course, something changed and all the reports needed to be remade. So then I wrote a Python script to manage the next build. (And the next, and the next, …). But I should have written a makefile. I’m about to have to revise the reports, and this time I’ll probably use a makefile.
Here’s a very simple example of using a makefile to create documents. For more extensive examples of how to use makefiles for a variety of tasks, see How I stopped worrying and loved Makefiles. [1]
Suppose you need to create a PDF and a Microsoft Word version of a report from a LaTeX file [2].
all: foo.pdf foo.docx foo.pdf: foo.tex pdflatex foo.tex foo.docx: foo.pdf pandoc foo.tex --from latex --to docx > foo.docx clean: rm foo.aux foo.log
If the file foo.pdf
does not exist, or exists but it older than foo.tex
, the command make foo.pdf
will create the PDF file by running pdflatex
. If foo.pdf
is newer than foo.tex
then running make foo.pdf
will return a message
make: 'foo.pdf' is up to date.
If you run make
with no argument, it will build both foo.pdf
and foo.docx
as needed.
The command make clean
deletes auxiliary files created by pdflatex
. This shows that a make
action does have to “make” anything; it simply runs a command.
[1] The blog post title is an allusion to the 1964 movie Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb.
[2] I use LaTeX for everything I can. This saves time in the long run, if not in the moment, because of consistency. I used to use Word for proposals and such, and LaTeX for documents requiring equations. My workflow became more efficient when I switched to using LaTeX for everything.
The post Making documents with makefiles first appeared on John D. Cook.