lilypond-usage: 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 GNU/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 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-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 ../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 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: SeeCommand-line usage, Seelilypond-book