Now, we’ll discuss the makefile and explain the rules already contained within it, as well as the rest.
TEXFILE = vXXXHere, we create the variable
TEXFILEto store the name of the main.texfile. When we want to use the variable later, we write$(TEXFILE).build/$(TEXFILE).pdfthen becomesbuild/vXXX.pdf.all: build/$(TEXFILE).pdfIt’s common practice to set
allas the initial target. In our case, that target is the PDF generated using LaTeX. Even though the makefile includespythonscripts, the files they produce are not the final objective of the lab course. After all, we’re required to submit a report, not just individual plots.build/plot.pdf: plot.py ../matplotlibrc ../header-matplotlib.tex | build TEXINPUTS=$$(pwd)/..: MATPLOTLIBRC=../matplotlibrc python plot.pyNow let’s look at the first rule in the makefile. All rules follow this structure. First comes the target file, then the files needed to create the target file (separated by a colon), and on the next line, indented by a tab, the command to be executed to create the target file. The
recipeis always executed if one of theprerequisiteshas a later access date than thetarget.target: prerequisites recipeIn this rule,
build/plot.pdfis created. This requiresplot.py, thepythonscript that carries out the evaluation, and the two configuration filesmatplotlibrcandheader-matplotlib.tex. These allow you to use LaTeX within thematplotlibplots. Both are in the main folder of the repository and therefore../must be added before the filenames so that they can be found. You can find more about LaTeX inmatplotlibin the LaTeX slides in the TeX section in matplotlib in TeX. In addition, you should also write your data files here, with a relative path to the makefile, e.g.data/quader.txt. The last thing on this line is| build. To save,pythonneeds thebuildfolder. The access date of this doesn’t matter. For this reason, it’s behind the pipe|. Here, it is only checked whether the folder exists.The
recipeconsists of several components. First,pythonis informed of the paths to the configuration files:TEXINPUTS=$$(pwd)/..:points toheader-matplotlib.tex, andMATPLOTLIBRC=../matplotlibrcpoints tomatplotlibrc. The remainder of the line is the commandpython plot.py.build/$(TEXFILE).pdf: build/plot.pdfThis line is a way to assign a dependency to a file without writing a full rule.
build/plot.pdfis included in the build process, so the file must exist before we build the main document using LaTeX.If you want to add another
pythonscript, you can add the following lines to your makefile. The filenames used here are<fit>; replace these five characters with your own filenames.build/<fit>.pdf: <fit>.py data/<fit>.py ../matplotlibrc ../header-matplotlib.tex | build TEXINPUTS=$$(pwd)/..: MATPLOTLIBRC=../matplotlibrc python <fit>.pyYou can then extend the line
build/$(TEXFILE).pdf: build/plot.pdfaccordingly. With the backslash\, the additional file can be placed on a new line. But, with more files, the line becomes longer and harder to read.build/$(TEXFILE).pdf: build/plot.pdf \ build/<fit>.pdfbuild/$(TEXFILE).pdf: FORCE | build TEXINPUTS=..: \ BIBINPUTS=..: \ max_print_line=1048576 \ latexmk \ --lualatex \ --output-directory=build \ --interaction=nonstopmode \ --halt-on-error \ $(TEXFILE).texThis is the long LaTeX rule. It includes everything discussed in the
makeslides. Theprerequisiteshere differ from those for thepythonrules. We discussed| buildin the context of thepythonrule, butFORCEis new here. It’s a dependency that is never satisfied. Further down in the Makefile, we also see a line containing onlyFORCE:. This ensures therecipeis always executed. This is intentionally written since we are callinglatexmkrather thanlualatex. You will also notice that we haven’t specified anywhere which.texfiles belong to this rule. We don’t need to becauselatexmkhandles that automatically once it identifies the main file. Let’s go through the individual lines of therecipe:TEXINPUTS=..: \: Theheader.texfile is located in the repository’s main folder. To ensurelatexmkfinds it, we extend the default search path (:). which includes the current folder and all subfolders, to also include the main folder. Using\allows us to visually split the line into several separate lines, though everything fromTEXINPUTSto$(TEXFILE).texis executed as a single line.BIBINPUTS=..: \: We also extend the search path for bibliography files, sincelit.bibandprogramme.bibare now located in the main folder. This is becauselatexmkdetects when you are usingbiberand executes everything in the correct order.max_print_line=1048576 \: With this line, we increase the number of characters allowed on a single line when running LaTeX. This makes the output look nicer and less choppy.latexmk \startslatexmkwith the following arguments:--lualatex: Useslualatexas the TeX engine.--output-directory=build \: All generated files are saved in thebuildfolder.--interaction=nonstopmode \: If errors occur,lualatex’s interactive error-handling mode is disabled.--halt-on-error \: If errors occur, the process is stopped.$(TEXFILE).tex: The file to be built.
build: mkdir -p buildWe have already discussed the
buildfolder in the rules. This is where it is created. It has no dependencies, so the first line ends after the colon:. The-pflag ensures that no error message is displayed if the folder already exists. Further, if we want to create a chain of folders (such asbuild/figures), all folders in the chain are created.clean: rm -rf buildIt’s good practice to have a command that returns the project to the state it was in before
makewas run. Since everything generated is stored in thebuildfolder, we only need to delete that folder. We use the-rfflags because we are deleting a folder (-r) and do not want an error message displayed if the object to be deleted does not exist (-f).FORCE:As described in the LaTeX rule, this is an always up-to-date
target..PHONY: all cleanThis is the final rule and is set so that
makeknows the listedtargetsdo not produce files, and (even if files with those names do exist) so that the rules will still be executed.
Running the makefile¶
If you want to use your Makefile, you have several options:
make: This command ensures that everything runs so that the latest version of theprerequisiteslisted in thealltargetis generated.make clean: Use this to clean up your experiment folder.make build/plot.pdf: Are you working on the plot or anotherpythonscript and want to view the results? You can then specify the correspondingtargetas an argument aftermake.