LilyPond Application Usage: 5.5 Make and Makefiles

## 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 X, 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 Linux and MacOS use `bash`, while Windows uses `cmd`. Note that on MacOS X, you need to configure the system to use the command-line interpreter. Here are some example makefiles, with versions for both 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-oboes.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 ../definitions.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 X. 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
>     # determine how many processors are present
>     CPU_CORES=`cat /proc/cpuinfo | grep -m1 "cpu cores" | sed s/".*: "//`
>     # The command to run lilypond
>     LILY_CMD = lilypond -ddelete-intermediate-files \
>                         -dno-point-and-click -djob-count=$(CPU_CORES)

>     # The suffixes used in this Makefile.
>     .SUFFIXES: .ly .ily .pdf .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)/PDF \
>       $(CURDIR)/Parts \
>       $(CURDIR)/Notes

>     # 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
>             $(LILY_CMD) $<; \           # this line begins with a tab
>             if test -f "$*.pdf"; then \
>                 mv "$*.pdf" PDF/; \
>             fi; \
>             if test -f "$*.midi"; then \
>                 mv "$*.midi" MIDI/; \
>             fi

>     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)
>     $(piece)II.pdf: $(piece)II.ly $(notes)
>     $(piece)III.pdf: $(piece)III.ly $(notes)
>     $(piece)IV.pdf: $(piece)IV.ly $(notes)

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

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

>     # 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 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)-oboes.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

>     archive:
>             tar -cvvf stamitz.tar \       # this line begins with a tab
>             --exclude=*pdf --exclude=*~ \
>             --exclude=*midi --exclude=*.tar \
>             ../Stamitz/*

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. The `archive` target is eliminated since Windows does not have the `tar` command, and Windows also has a different default extension for midi files.

>     ## WINDOWS VERSION
>     ##
>     piece = symphony
>     LILY_CMD = lilypond -ddelete-intermediate-files \
>                         -dno-point-and-click \
>                         -djob-count=$(NUMBER_OF_PROCESSORS)

>     #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

>     VPATH = \
>       $(workdir)/Scores \
>       $(workdir)/PDF \
>       $(workdir)/Parts \
>       $(workdir)/Notes

>     %.pdf %.mid: %.ly
>             $(LILY_CMD) $<      # this line begins with a tab
>             if exist "$*.pdf"  move /Y "$*.pdf"  PDF/ # begin with tab
>             if exist "$*.mid" move /Y "$*.mid" MIDI/  # begin with tab

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

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

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

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

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

>     .PHONY: parts
>     parts: $(piece)-cello.pdf \
>            $(piece)-violinOne.pdf \
>            $(piece)-violinTwo.pdf \
>            $(piece)-viola.pdf \
>            $(piece)-oboes.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`

Jiné jazyky: deutsch, español, français, magyar, italiano, 日本語.

#### LilyPond — Usage