5.5 Make and Makefiles

Pretty well all the platforms LilyPond can run on support a software facility called make. This software reads a special file called a Makefile that defines what files depend on what others and what commands you need to give the operating system to produce one file from another. For example the makefile would spell out how to produce ballad.pdf and ballad.midi from ballad.ly by running LilyPond.

There are times when it is a good idea to create a Makefile for your project, either for your own convenience or as a courtesy to others who might have access to your source files. This is true for very large projects with many included files and different output options (e.g., full score, parts, conductor’s score, piano reduction, etc.), or for projects that require difficult commands to build them (such as lilypond-book projects). Makefiles vary greatly in complexity and flexibility, according to the needs and skills of the authors. The program GNU Make comes installed on GNU/Linux distributions and on macOS, and it is also available for Windows.

See the GNU Make Manual for full details on using make, as what follows here gives only a glimpse of what it can do.

The commands to define rules in a makefile differ according to platform; for instance the various forms of GNU/Linux and macOS use bash, while Windows uses cmd. Note that on macOS, you need to configure the system to use the command-line interpreter. Here are some example makefiles, with versions for both GNU/Linux/macOS and Windows.

The first example is for an orchestral work in four movements with a directory structure as follows:

Symphony/
|-- MIDI/
|-- Makefile
|-- Notes/
|   |-- cello.ily
|   |-- figures.ily
|   |-- horn.ily
|   |-- oboe.ily
|   |-- trioString.ily
|   |-- viola.ily
|   |-- violinOne.ily
|   `-- violinTwo.ily
|-- PDF/
|-- Parts/
|   |-- symphony-cello.ly
|   |-- symphony-horn.ly
|   |-- symphony-oboe.ly
|   |-- symphony-viola.ly
|   |-- symphony-violinOne.ly
|   `-- symphony-violinTwo.ly
|-- Scores/
|   |-- symphony.ly
|   |-- symphonyI.ly
|   |-- symphonyII.ly
|   |-- symphonyIII.ly
|   `-- symphonyIV.ly
`-- symphonyDefs.ily

The .ly files in the Scores and Parts directories get their notes from .ily files in the Notes directory:

%%% top of file "symphony-cello.ly"
\include "../symphonyDefs.ily"
\include "../Notes/cello.ily"

The makefile will have targets of score (entire piece in full score), movements (individual movements in full score), and parts (individual parts for performers). There is also a target archive that will create a tarball of the source files, suitable for sharing via web or email. Here is the makefile for GNU/Linux or macOS. It should be saved with the name Makefile in the top directory of the project:

Note: When a target or pattern rule is defined, the subsequent lines must begin with tabs, not spaces.

# the name stem of the output files
piece := symphony
# The command to run lilypond
LILY_CMD := lilypond -ddelete-intermediate-files \
                    -dno-point-and-click

# The suffixes used in this Makefile.
.SUFFIXES: .ly .ily .pdf .midi

.DEFAULT_GOAL := score

PDFDIR := PDF
MIDIDIR := MIDI

# Input and output files are searched in the directories listed in
# the VPATH variable.  All of them are subdirectories of the current
# directory (given by the GNU make variable `CURDIR`).
VPATH := \
  $(CURDIR)/Scores \
  $(CURDIR)/Parts \
  $(CURDIR)/Notes \
  $(CURDIR)/$(PDFDIR) \
  $(CURDIR)/$(MIDIDIR)

# The pattern rule to create PDF and MIDI files from a LY input file.
# The .pdf output files are put into the `PDF` subdirectory, and the
# .midi files go into the `MIDI` subdirectory.
%.pdf %.midi: %.ly | $(PDFDIR) $(MIDIDIR)
	$(LILY_CMD) $<          	# this line begins with a tab
	mv "$*.pdf" $(PDFDIR)/		# this line begins with a tab
	mv "$*.midi" $(MIDIDIR)/	# this line begins with a tab

$(PDFDIR):
	mkdir $(PDFDIR)

$(MIDIDIR):
	mkdir $(MIDIDIR)

common := symphonyDefs.ily

notes := \
  cello.ily \
  horn.ily \
  oboe.ily \
  viola.ily \
  violinOne.ily \
  violinTwo.ily

# The dependencies of the movements.
$(piece)I.pdf: $(piece)I.ly $(notes) $(common)
$(piece)II.pdf: $(piece)II.ly $(notes) $(common)
$(piece)III.pdf: $(piece)III.ly $(notes) $(common)
$(piece)IV.pdf: $(piece)IV.ly $(notes) $(common)

# The dependencies of the full score.
$(piece).pdf: $(piece).ly $(notes) $(common)

# The dependencies of the parts.
$(piece)-cello.pdf: $(piece)-cello.ly cello.ily $(common)
$(piece)-horn.pdf: $(piece)-horn.ly horn.ily $(common)
$(piece)-oboe.pdf: $(piece)-oboe.ly oboe.ily $(common)
$(piece)-viola.pdf: $(piece)-viola.ly viola.ily $(common)
$(piece)-violinOne.pdf: $(piece)-violinOne.ly violinOne.ily $(common)
$(piece)-violinTwo.pdf: $(piece)-violinTwo.ly violinTwo.ily $(common)

# Type `make score` to generate the full score of all four
# movements as one file.
.PHONY: score
score: $(piece).pdf

# Type `make parts` to generate all parts.
# Type `make symphony-foo.pdf` to generate the part for instrument 'foo'.
# Example: `make symphony-cello.pdf`.
.PHONY: parts
parts: $(piece)-cello.pdf \
       $(piece)-violinOne.pdf \
       $(piece)-violinTwo.pdf \
       $(piece)-viola.pdf \
       $(piece)-oboe.pdf \
       $(piece)-horn.pdf

# Type `make movements` to generate files for the
# four movements separately.
.PHONY: movements
movements: $(piece)I.pdf \
           $(piece)II.pdf \
           $(piece)III.pdf \
           $(piece)IV.pdf

all: score parts movements

There are special complications on the Windows platform. After downloading and installing GNU Make for Windows, you must set the correct path in the system’s environment variables so that the DOS shell can find the Make program. To do this, right-click on "My Computer," then choose Properties and Advanced. Click Environment Variables, and then in the System Variables pane, highlight Path, click edit, and add the path to the GNU Make executable file, which will look something like this:

C:\Program Files\GnuWin32\bin

The makefile itself has to be altered to handle different shell commands and to deal with spaces that are present in some default system directories. Windows also has a different default extension for midi files.

## WINDOWS VERSION
##
piece := symphony
LILY_CMD := lilypond -ddelete-intermediate-files \
                    -dno-point-and-click

#get the 8.3 name of CURDIR (workaround for spaces in PATH)
workdir := $(shell for /f "tokens=*" %%b in ("$(CURDIR)") \
          do @echo %%~sb)

.SUFFIXES: .ly .ily .pdf .mid

.DEFAULT_GOAL := score

PDFDIR := PDF
MIDIDIR := MIDI

VPATH := \
  $(workdir)/Scores \
  $(workdir)/Parts \
  $(workdir)/Notes \
  $(workdir)/$(PDFDIR) \
  $(workdir)/$(MIDIDIR)

%.pdf %.mid: %.ly | $(PDFDIR) $(MIDIDIR)
        $(LILY_CMD) $<			# this line begins with a tab
        move /Y "$*.pdf"  $(PDFDIR)/	# begin with tab
        move /Y "$*.mid" $(MIDIDIR)/	# begin with tab

$(PDFDIR):
    mkdir $(PDFDIR)/

$(MIDIDIR):
    mkdir $(MIDIDIR)/

notes := \
  cello.ily \
  figures.ily \
  horn.ily \
  oboe.ily \
  trioString.ily \
  viola.ily \
  violinOne.ily \
  violinTwo.ily

common := symphonyDefs.ily

$(piece)I.pdf: $(piece)I.ly $(notes) $(common)
$(piece)II.pdf: $(piece)II.ly $(notes) $(common)
$(piece)III.pdf: $(piece)III.ly $(notes) $(common)
$(piece)IV.pdf: $(piece)IV.ly $(notes) $(common)

$(piece).pdf: $(piece).ly $(notes) $(common)

$(piece)-cello.pdf: $(piece)-cello.ly cello.ily $(common)
$(piece)-horn.pdf: $(piece)-horn.ly horn.ily $(common)
$(piece)-oboe.pdf: $(piece)-oboe.ly oboe.ily $(common)
$(piece)-viola.pdf: $(piece)-viola.ly viola.ily $(common)
$(piece)-violinOne.pdf: $(piece)-violinOne.ly violinOne.ily $(common)
$(piece)-violinTwo.pdf: $(piece)-violinTwo.ly violinTwo.ily $(common)

.PHONY: score
score: $(piece).pdf

.PHONY: parts
parts: $(piece)-cello.pdf \
       $(piece)-violinOne.pdf \
       $(piece)-violinTwo.pdf \
       $(piece)-viola.pdf \
       $(piece)-oboe.pdf \
       $(piece)-horn.pdf

.PHONY: movements
movements: $(piece)I.pdf \
           $(piece)II.pdf \
           $(piece)III.pdf \
           $(piece)IV.pdf

all: score parts movements

The next Makefile is for a lilypond-book document done in LaTeX. This project has an index, which requires that the latex command be run twice to update links. Output files are all stored in the out directory for .pdf output and in the htmlout directory for the html output.

SHELL=/bin/sh
FILE=myproject
OUTDIR=out
WEBDIR=htmlout
VIEWER=acroread
BROWSER=firefox
LILYBOOK_PDF=lilypond-book --output=$(OUTDIR) --pdf $(FILE).lytex
LILYBOOK_HTML=lilypond-book --output=$(WEBDIR) $(FILE).lytex
PDF=cd $(OUTDIR) && pdflatex $(FILE)
HTML=cd $(WEBDIR) && latex2html $(FILE)
INDEX=cd $(OUTDIR) && makeindex $(FILE)
PREVIEW=$(VIEWER) $(OUTDIR)/$(FILE).pdf &

all: pdf web keep

pdf:
        $(LILYBOOK_PDF)  # begin with tab
        $(PDF)           # begin with tab
        $(INDEX)         # begin with tab
        $(PDF)           # begin with tab
        $(PREVIEW)       # begin with tab

web:
        $(LILYBOOK_HTML) # begin with tab
        $(HTML)          # begin with tab
        cp -R $(WEBDIR)/$(FILE)/ ./  # begin with tab
        $(BROWSER) $(FILE)/$(FILE).html &  # begin with tab

keep: pdf
        cp $(OUTDIR)/$(FILE).pdf $(FILE).pdf  # begin with tab

clean:
        rm -rf $(OUTDIR) # begin with tab

web-clean:
        rm -rf $(WEBDIR) # begin with tab

archive:
        tar -cvvf myproject.tar \ # begin this line with tab
        --exclude=out/* \
        --exclude=htmlout/* \
        --exclude=myproject/* \
        --exclude=*midi \
        --exclude=*pdf \
        --exclude=*~ \
        ../MyProject/*

TODO: make this thing work on Windows

The previous makefile does not work on Windows. An alternative for Windows users would be to create a simple batch file containing the build commands. This will not keep track of dependencies the way a makefile does, but it at least reduces the build process to a single command. Save the following code as build.bat or build.cmd. The batch file can be run at the DOS prompt or by simply double-clicking its icon.

lilypond-book --output=out --pdf myproject.lytex
cd out
pdflatex myproject
makeindex myproject
pdflatex myproject
cd ..
copy out\myproject.pdf MyProject.pdf

See also

This manual: Command-line usage, Running lilypond-book.


LilyPond Application Usage v2.25.20 (development-branch).