forked from cornell-brg/albs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
albs-uguide.txt
876 lines (721 loc) · 37.9 KB
/
albs-uguide.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
==========================================================================
Automatic LaTeX Build System User Guide
==========================================================================
# Author : Christopher Batten
# Date : November 29, 2008
The Automatic LaTeX Build System (ALBS) is a set of makefiles, scripts,
and policies for managing large LaTeX projects. We use the term
"project" instead of "document", since a project includes all of the
source files, the scripts, and the build system to generate one or more
"documents". The build system helps track dependencies, efficiently run
the toolflow, and manage different types of input. Currently the build
system only works with 'pdflatex'. This user guide is divided into two
parts: the first part is a tutorial, and the second part contains
general user reference.
Table of Contents
Part 1: Tutorial
1.1. Building a Project
1.2. Adding LaTeX Source Files
1.3. Adding SVG Figures
1.4. Adding a New Build System Module
1.5. Prebuilding Module Output
Part 2: Reference
2.1. Basic Autoconf Toolflow
2.2. Basic Make Toolflow
2.3. Build System Modules
--------------------------------------------------------------------------
1. Tutorial
--------------------------------------------------------------------------
This part walks through using the Automatic LaTeX Build System to create
a new document, add figures, and add a new build system module. You can
follow along through the tutorial yourself by typing in the commands
marked with a '%' symbol at the shell prompt. Tasks to try on your own
are denoted with (*). To cut and paste commands from this tutorial into
your bash shell (and make sure bash ignores the '%' character) just use
an alias to "undefine" the '%' character like this:
% alias %=""
Before creating a new project we need to decide what to name the
project, and thus the primary document. For this tutorial we will use
the abbreviated name 'mcppbs-tut'. So the first step is to create a
directory with the project name, and to simplify the rest of the
tutorial we will also define a '$PROJROOT' environment variable which
contains the absolute path to the project's toplevel root directory.
% mkdir albs-tut
% cd albs-tut
% PROJROOT=$PWD
To instantiate the build system, we need to first download the 'albs'
template from the public git repository and then we will add some
metadata about our project to 'configure.ac'
% TGZ=http://gitorious.org/cbatten-sw/albs/archive-tarball/master
% wget -O- $TGZ | tar xzf -
Take a look at the files in the toplevel project directory.
- 'README' : Project documentation
- 'albs-uguide.txt' : Build system user guide
- 'configure.ac' : Input for autoconf tools
- 'aclocal.m4' : Local macros for autoconf tools
- 'Makefile.in' : Template used by 'configure' script
- 'configure' : Generated by 'autoconf'
- 'scripts' : Subdirectory with build system scripts
- 'src' : Subdirectory for LaTeX source files
- 'images' : Subdirectory for various image files
- 'svg' : Subdirectory for SVG build system module
- 'py' : Subdirectory for Python build system module
The build system uses the GNU Autoconf tools to configure the system for
the current build platform, and the GNU Make tools to manage the actual
build process. For more details about these tools see the second part of
this guide. The build system organizes the input files into
subdirectories. All of the LaTeX source code should go in the 'src'
subdirectory, all of the images to be included in the document should go
in the 'images' subdirectory, and other file formats should go in the
appropriate build system module subdirectory (to be discussed later).
After acquiring the template, we need to update the metadata in
'configure.ac' with the new project's name, maintainer's name, and a
shorter abbreviated form of the project name. The abbreviated form
should be all lowercase, use a dash as a separator, and usually is the
same as the project directory name. We want to change the metadata in
'configure.ac' so that it looks like this:
m4_define( proj_name, [ALBS Tutorial])
m4_define( proj_maintainer, [Christopher Batten])
m4_define( proj_abbreviation, [albs-tut])
m4_define( proj_version, [0.0])
For the tutorial we use sed to make the change, but you can also use
your favorite text editor. Note that after we change 'configure.ac' we
need to rerun the autoconf tools.
% cd $PROJROOT
% sed -i.bak \
-e 's/\( proj_name,\).*/\1 [ALBST Tutorial])/' \
-e 's/\( proj_maintainer,\).*/\1 [Christopher Batten])/' \
-e 's/\( proj_abbreviation,\).*/\1 [albs-tut])/' \
-e 's/\( proj_version,\).*/\1 [0.0])/' configure.ac
% autoconf
This might also be a good time to update the 'README' with information
specific to the new project. You are encouraged to keep a pointer in the
'README' to the documentation on the build system ('albs-uguide.txt') so
that your end-users can learn how the build system works.
The build system assumes that the default toplevel LaTeX file has the
same name as your project, so we need to rename the 'albs.tex' and
'albs.bib' files in the 'src' subdirectory.
% cd $PROJROOT/src
% mv albs.tex albs-tut.tex
% mv albs.bib albs-tut.bib
Take a look at the toplevel 'albs-tut.tex' file. Since we changed the
name of the bibliography we also need to change the corresponding
'bibliography' line in 'albs-tut.tex'.
% cd $PROJROOT/src
% sed -i.bak -e 's/\(bibliography{\)albs/\1albs-tut/' albs-tut.tex
--------------------------------------------------------------------------
1.1. Building a Project
--------------------------------------------------------------------------
The first thing we will try is just building the project. The build
system is structured so that we do not intermingle the generated files
with the source files. This makes it much easier to manage larger
projects. You should _always_ create a separate build directory in which
to build the project. To do a clean build you just need to delete the
build directory and start over. The following commands create a build
directory, configure the project, and then build the project.
% cd $PROJROOT
% mkdir build
% cd build
% ../configure
% make
Notice that we run the portable 'configure' shell script to customize
the build system for the current platform. The 'configure' script
displays information about what kind of checks it is performing. You can
see that it is checking if 'pdflatex' and 'bibtex' are installed. The
build system uses a few critical Ruby scripts, so we also check to see
if Ruby is installed.
Take a look at the generated document in 'albs-tut.pdf'. Also look
through the other files in the build directory. You should see the
following files:
- 'Makefile' : 'configure' generated makefile
- 'config.log' : Log from 'configure' script
- 'config.status' : Cached version of the 'configure' script
- 'svg.mk' : Makefile fragment for SVG build system module
- 'py.mk' : Makefile fragment for Python build system module
- 'albs-tut.d' : Auto-generated dependency file
- 'albs-tut.log' : Log file from running LaTeX
- 'albs-tut.out' : Output from running LaTeX
- 'albs-tut.aux' : Auxiliary file generated by LaTeX
- 'albs-tut.pdf' : Final document PDF
The 'configure' script takes the 'Makefile.in' file in the project root
directory and makes some substitutions for special variables denoted
with the '@variable@' syntax. Look for '@srcdir@' in 'Makefile.in' and
compare that line to the same line in the generated 'Makefile'. You can
see that the 'configure' script has substituted the correct path to the
toplevel directory for the LaTeX project. No matter where you put the
build directory, 'configure' will fill this variable in correctly so
that the build system can always find the source files. Also take a look
at the final document PDF. We will talk more about the other files later
in the tutorial.
To clean up the build directory we can use the 'clean' make target. Take
a look at what is in the build directory before and after running 'make
clean'. Afterwards you should just see the scripts generated by
'configure'.
% cd $PROJROOT/build
% make clean
--------------------------------------------------------------------------
1.2. Adding LaTeX Source Files
--------------------------------------------------------------------------
LaTeX source files should always be placed in the 'src' subdirectory.
Let's add a new source file named 'secA.tex' which contains the first
section in the document.
% cd $PROJROOT/src
% cat > secA.tex \
<<'END'
\section{Section A}
\label{secA}
This document has multiple sections (see Section~\ref{secB}).
END
We also add a second source file named 'secB.tex' which contains the
second section. Notice that both files have cross-references to each
other.
% cd $PROJROOT/src
% cat > secB.tex \
<<'END'
\section{Section B}
\label{secB}
This document has multiple sections (see Section~\ref{secA}).
END
Finally, we update the toplevel 'albs-tut.tex' file to include both
sections.
% cd $PROJROOT/src
% sed -i.bak '/% Body/ a \
\\input{secA} \
\\input{secB} ' albs-tut.tex
After making these changes we can rebuild the project. Take notice of
how many times the build system runs LaTeX.
% cd $PROJROOT/build
% make
If you look closely when rebuilding the document, you will see that the
build system runs LaTeX twice so that it can correctly resolve the
cross-references. The build system uses a custom script
('scripts/run-latex.rb') which determines the minimal number of times to
run LaTeX and BibTeX while still producing correct output (see the
reference documentation later in this guide for more information).
Now try touching the 'secA.tex' file and rerun make.
% cd $PROJROOT/build
% touch ../src/secA.tex
% make
Notice that it only runs LaTeX once because none of the cross-references
have changed. Also notice that the build system automatically determined
that it needed to rebuild the project even though the toplevel source
file ('albs-tut.tex') did not change. The build system includes a second
custom script ('scripts/mk-latex-deps.mk') which scans LaTeX source
files recursively looking for dependencies and then generates a makefile
fragment which contains these dependencies. Take a look in
'build/albs-tut.d' to see what one of the makefile fragments looks like.
If you look closely, you can see that the fragment creates a dependency
between the final PDF file ('albs-tut.pdf') and the section source files
('secA.tex', 'secB.tex').
(*) Try adding additional section files with more cross-references to
verify that the build system correctly detects the various dependencies
and runs LaTeX the correct number of times. (*) Add a BibTeX entry, cite
the reference in one of the sections, and verify that everything works
correctly.
--------------------------------------------------------------------------
1.3. Adding SVG Figures
--------------------------------------------------------------------------
By default, the build system supports automatically converting SVG
figures to PDF for inclusion in LaTeX documents. To see how this works,
let's first create a new SVG figure. All SVG source files should be
placed in the 'svg' subdirectory. Normally we use Inkscape to create the
SVG files, but since SVG is just a plain text file format we can also
create simple figures manually. The following SVG code creates two
overlapping circles.
% cd $PROJROOT/svg
% cat > circles.svg \
<<'END'
<svg>
<circle cx='0' cy='0' r='40' style='fill: red' />
<circle cx='30' cy='0' r='40' style='fill: blue' />
</svg>
END
The build system will only convert this SVG file if it is actually used
by the LaTeX source. So we now use the 'includegraphics' macro to
include the circles drawing. We don't include 'circles.svg' because
LaTeX does not understand SVG files. Instead we include
'circles.svg.pdf'. The 'mk-latex-deps.rb' script will find this
dependency, and then the build system will automatically know it should
create 'circles.svg.pdf' from 'circles.svg' using Inkscape. First, we
include the circles figure in the one of the sections.
% cd $PROJROOT/src
% sed -i.bak '/\\label{secA}/ a \
\\includegraphics{circles.svg.pdf}' secA.tex
Now we rebuild the project.
% cd $PROJROOT/build
% make
If you look closely at the output you will see that the build system
runs 'inkscape' from the command line to convert the SVG file to EPS.
Then the 'epstopdf' command is used to generate 'circles.svg.pdf' in the
build directory. Take a look at 'circles.svg.pdf' to verify that it is a
diagram of two overlapping circles. This generated PDF file is the
figure which is actually included in the final document by LaTeX. The
build system only reconverts the image if the original SVG changes.
(*) Try adding another SVG image and notice that only the new image is
converted to PDF. If you use the 'touch' command to update both images,
then the build system will reconvert both of them.
--------------------------------------------------------------------------
1.4. Adding a New Build System Module
--------------------------------------------------------------------------
The build system's support for SVG files is an example of a build system
module. These modules help automate the process of converting various
input formats into a form suitable for use in a LaTeX document. A module
includes autoconf fragments (eg. 'svg/svg.ac'), makefile fragments
(eg. 'svg/svg.mk.in'), and a small LaTeX package (eg. 'svg/svg.sty') as
well as the corresponding input files (eg. 'svg/*.svg'). Take some time
to look at how the SVG build system module is implemented. In this
section we will add a new module which supports the Graphviz DOT format
('http://www.graphviz.org').
The Graphviz DOT format provides a clean syntax for expressing the
fundamental connectivity in a graph. The format does not specify how to
layout the graph. Instead we use the 'dot' command to layout the graph
and generate the actual diagram. To see how this works, let's first
create an example DOT file.
% cd $PROJROOT/build
% cat > graph.dot \
<<'END'
digraph G
{
A -> C;
B -> C;
}
END
This file specifies a simple graph with three nodes labelled 'A', 'B',
and 'C'. There are two edges connecting 'A' to 'C' and 'B' to 'C'. We
can now run the 'dot' command to layout this graph and generate a
diagram in PDF format.
% cd $PROJROOT/build
% dot -Tpdf -o graph.dot.pdf graph.dot
The '-T' command line argument specifies the output format and the '-o'
command line argument specifies the name of the output file. Take a look
at the resulting 'graph.dot.pdf' file to see what the graph looks like.
Notice that there is a margin around the graph. When including PDF files
in LaTeX files we usually want to avoid these kind of margins since it
can make it difficult to manage figure spacing from with LaTeX. We can
use the 'pdfcrop' command (usually included with LaTeX distributions) to
remove the margins.
% cd $PROJROOT/build
% pdfcrop graph.dot.pdf graph.dot.pdf
We use the same name for the input and output files so the
'graph.dot.pdf' file is overwritten with the cropped version. Take
another look at the resulting PDF file to verify that the margins have
been removed. Let's delete these temporary files.
% cd $PROJROOT/build
% rm -rf graph.dot graph.dot.pdf
We now want to improve our build system so it automatically handles the
conversion from DOT files to PDF files. One approach is to just add some
code to the toplevel 'configure.ac' and 'Makefile.in'. Unfortunately,
this results in monolithic scripts as we continue to add more input file
formats. So instead, we create a build system module. A build system
module is just a subdirectory in the toplevel project directory with
specific script fragments. The first thing we need to do is create this
subdirectory. The name of the module and the corresponding subdirectory
should be short, all lowercase, and usually reflect the type of files
that module handles. We name our new module 'dot'.
% cd $PROJROOT
% mkdir dot
Next we need to add an autoconf fragment ('dot.ac'), a makefile fragment
('dot.mk.in'), and a small LaTeX package ('dot.sty'). First the autoconf
fragment. This fragment should perform checks to make sure that the
tools required to do the conversion are available. In this case, this
means checking to make sure both the 'dot' command and the 'pdfcrop'
command are installed.
% cd $PROJROOT/dot
% cat > dot.ac \
<<'END'
AC_CHECK_PROGS([dot],[dot],[no])
AC_CHECK_PROGS([pdfcrop],[pdfcrop],[no])
AS_IF([test "$dot" = "no" || test "$pdfcrop" = "no"],
[
AC_MSG_WARN([Could not find either dot or pdfcrop])
AC_MSG_WARN([You will be unable to convert DOT to PDF])
dot_enabled=no
],[
dot_enabled=yes
])
END
The autoconf fragment is written in the m4 macro language. The
'AC_CHECK_PROGS' macro will see if the given command is in the current
path and if so set a make variable appropriately. So in this example, if
'dot' is available then it will set the 'dot' make variable to 'dot'. If
the 'dot' command might have other names then we could check for those
other versions as well and set the 'dot' make variable to whichever one
is found. If 'dot' is not found then the 'dot' make variable is to 'no'.
After checking for the 'dot' and the 'pdfcrop' commands, we see if
_both_ are available and if so then we set the 'dot_enabled' make
variable to 'yes'.
If either 'dot' or 'pdfcrop' is not available then we could decide to
halt the configuration with an error, but instead we just display a
warning. This is because it is common for one user to prebuild a bunch
of content (eg. all the PDFs corresponding to the DOT files) and then
check these prebuilt files into the repository. Another user can then
checkout the project and build the document even if they don't have
'dot' or 'pdfcrop' installed as long as they don't change the original
DOT files. We discuss prebuilding later in this tutorial.
The next step is to create a makefile fragment ('doc.mk.in'). Notice
that this fragment has the '.in' extension indicating that it will be
processed by the 'configure' script. Our makefile fragment needs to
contain rules which specify how to create PDF files from DOT files.
% cd $PROJROOT/dot
% cat > dot.mk.in \
<<'END'
DOT = @dot@
PDFCROP = @pdfcrop@
dot_enabled = @dot_enabled@
dot_figs = $(filter %.dot.pdf, $(figs))
dot_prebuild = $(dot_figs)
ifeq ($(dot_enabled),yes)
$(dot_figs) : %.dot.pdf : %.dot
<TAB>$(DOT) -Tpdf $< -o $@
<TAB>$(PDFCROP) $*.dot.pdf $*.dot.pdf
endif
junk += $(dot_figs)
END
First we set two make variables with the appropriate 'dot' and 'pdfcrop'
commands. Then we create a list of all the figures in the project which
have the '.dot.pdf' extension. A pattern substitution rule which
specifies that every file in the 'dot_figs' make variable depends on a
corresponding '.dot' file. To make the PDF file, we first run 'dot' and
then we run 'pdfcrop'. Notice that the rule is wrapped in a conditional
test if '@dot_enabled@' equals 'yes'. So if the 'configure' script could
not find the required commands, the makefile will not include this rule
at all. Finally, we update the running 'junk' variable with the
generated PDF files so that the 'clean' make target will correctly
delete them. Note that you will need to replace '<TAB>' with a real tab
character in order for this make fragment to actually work.
The final piece of the build system module is a small LaTeX package
which calls any necessary LaTeX macros required by this module.
% cd $PROJROOT/dot
% cat > dot.sty \
<<'END'
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{dot}[2008/10/09 ver 0.1]
\RequirePackage{graphicx}
\DeclareGraphicsRule{.dot.pdf}{pdf}{.dot.pdf}{}
END
The first two lines are standard in all LaTeX packages. We use the
'RequirePackage' macro to make sure that the 'graphicx' package is
loaded, and we use the 'DeclareGraphicsRule' macro to tell the
'graphicx' package that '.dot.pdf' is a valid extension for graphics
files.
Now that we have written our module we need to tell the build system to
use the new module. We do this by adding the module to the
'ALBS_MODULES' macro in the toplevel 'configure.ac' and rerunning
autoconf.
% cd $PROJROOT
% sed -i.bak 's/\(ALBS_MODULES(\[svg,mat\)/\1,dot/' configure.ac
% autoconf
We are now ready to create a DOT file and include it in our LaTeX
document. We will use the same graph as before, except that now we place
the DOT file in the 'dot' subdirectory. All input files should be placed
in the appropriate module subdirectory.
% cd $PROJROOT/dot
% cat > graph.dot \
<<'END'
digraph G
{
A -> C;
B -> C;
}
END
We need to add a 'usepackge' macro call to the toplevel LaTeX file.
% cd $PROJROOT/src
% sed -i.bak '/\\usepackage{svg}/ a \
\\usepackage{dot}' albs-tut.tex
We include the generated PDF file in the second section.
% cd $PROJROOT/src
% sed -i.bak '/\\label{secB}/ a \
\\includegraphics{graph.dot.pdf}' secB.tex
Finally, we can rebuild the project.
% cd $PROJROOT/build
% make
If you look at the output during the build process you will first see
that the build system reruns configure since the script has been changed
by autoconf. You will also see the 'dot' and 'pdfcrop' commands being
used to convert 'graph.dot' into 'graph.dot.pdf'. If you take a look at
'albs-tut.pdf' you should see the graph has been included in the
document. (*) Try adding another graph and rebuilding the project. (*)
Also try modifying one of the source DOT files and verify that the final
document is updated appropriately.
--------------------------------------------------------------------------
1.5. Prebuilding Module Output
--------------------------------------------------------------------------
Ideally we would always generate all the intermediate files (eg. the PDF
files generated from the SVG source files) from scratch every time we
checked out the project. Unfortunately, we may be collaborating with
others on the project and they may or may not have the proper tools
installed to generate these intermediate files. Since these
collaborators might just want to edit the LaTeX source files (as opposed
to editing the SVG source files for example) we can prebuild the
intermediate files and check them into our source repository. Others can
use these prebuilt files and those with the proper tools can convert
(and thus edit) the figures. The build system provides a very convenient
way for managing these prebuilt files.
The first step is to actually do the prebuild. We do this with the
'prebuild' make target.
% cd $PROJROOT/build
% make prebuild
You should see that the generated 'circles.dot.pdf' and 'graph.dot.pdf'
files are copied into a newly created 'prebuild' subdirectory of the
toplevel directory. We could now check in the prebuild directory. To see
how we can use these prebuilt files, we will reconfigure our project
without SVG and DOT support.
% cd $PROJROOT/build
% make distclean
% ../configure --without-svg --without-dot
If you look at the output from the 'configure' script you will see that
it skips over checking for 'inkscape', 'epstopdf', 'dot', and 'pdfcrop'.
This has the same effect as if those tools were not installed. If we now
try and build the project you can see that the build system will copy
the prebuilt files from the prebuild directory.
% cd $PROJROOT/build
% make
If someone forgets to actually prebuild a file which you cannot build
yourself, then you will see a make error like this:
make: *** No rule to make target `../prebuild/circles.svg.pdf', ...
The fact that the target file is in the 'prebuild' directory is a clue
that the file is not provided - possibly someone forgot to run
'prebuild' and check in the results. You can prebuild the files for just
one module by using a target like 'prebuild-svg' and you can clean all
of the prebuilt files with the 'clean-prebuild' target.
We are now done with the tutorial, so we can remove the tutorial's
working directory.
% rm -rf $PROJROOT
--------------------------------------------------------------------------
2. Reference
--------------------------------------------------------------------------
In this section we provide more detailed reference on the various parts
of the build system including how the Autoconf and Make toolflow works
as well as some more details on the build system modules.
--------------------------------------------------------------------------
2.1. Basic Autoconf Toolflow
--------------------------------------------------------------------------
The Automatic LaTeX Build System uses the GNU Autoconf tools to help
make sure the build process is portable across various platforms. At
first, this might seem like overkill, but leveraging autoconf can be
particularly useful when trying to make sure all the various tools
required to build a document are installed and working on a given
platform. For example, we can check to see if a specific image
conversion tool is available on the current platform and if not we can
display a warning. The basic toolflow for using the GNU Autoconf tools
is shown below:
(configure.ac)--.
+--->[autoconf]--->([configure])--->(Makefile)
(aclocal.m4)---' /
/
(Makefile.in)-------------------------'
In this figure, files are denoted with parentheses '()' and tools are
denoted with brackets '[]'. The process begins with the 'configure.ac'
script which is "written" in the m4 macro language. This script contains
macros which tell the build system about the project and also specify
various checks to perform. For example, it might specify that we should
check for to make sure a certain image converter is installed. Based on
these checks, the build system can change our makefile. The 'aclocal.m4'
file contains additional macro functions that can be used with the
standard autoconf macros in 'configure.ac'. Macros specific to the
Automatic LaTeX Build System use the 'ALBS_' prefix and are included in
the 'aclocal.m4' file.
The 'configure.ac' script is used as input to the 'autoconf' command
which generates a portable shell script named 'configure'. The
'configure' shell script is executed by the end-user to customize the
build system for their specific platform. The 'configure' script is
annotated with '([])' since it is a file which is generated by
'autoconf', but then it is executed as a tool to customize the build
system for the current platform. The 'configure' script takes as input
the 'Makefile.in' and does variable substitutions to generate the
'Makefile'. For example, if a specific image converter is installed we
might conditionally enable a rule in our 'Makefile' to allows us to
automatically do this type of conversion. Once the 'Makefile' is
generated we can use 'make' to build the project. To regenerate the
'configure' script users can just execute the following command in the
toplevel project directory.
> autoconf
Given the basic GNU Autoconf toolflow, the following commands will
create a new build directory and configure the build system (assuming we
start in the toplevel project directory).
> mkdir build
> cd build
> ../configure
Note that most of the time we don't actually need to rerun 'autoconf';
we just execute the portable 'configure' shell script to do the
configuration. We only need to rerun 'autoconf' when we change
'configure.ac'. So to simplify the build process for the end-users we
should always include the 'configure' script in the distribution.
New projects need to update 'configure.ac' with the project's name,
version number, maintainer's name, and the shorter abbreviated project
name. They then need to rerun 'autoconf'. Here is an example of what
this metadata looks like in 'configure.ac':
m4_define( proj_name, [Example LaTeX Document])
m4_define( proj_maintainer, [Christopher Batten])
m4_define( proj_abbreviation, [exld])
The project abbreviation name should be the same as the name of the
toplevel LaTeX file and it should use lowercase letters as well as
dashes. This is just a very simplified description of the autoconf
toolflow.
The version metadata deserves special mention. Usually we are working on
a project which is checked into some kind of version control system
(VCS). In this case we don't really want to hard-code a version number
into the 'configure.ac' file since it will quickly be out of date with
respect to the VCS. So instead we usually mark the version as '?' in the
'configure.ac' file and just use the standard VCS files to track
revisions. When we make a distribution tarball though, the source code
is exported from the VCS and we will loose version information. So the
build system includes a script called 'vcs-version.sh' in the 'scripts'
subdirectory which creates a version string suitable from the VCS. We
can then use this string in the distribution. The makefile's 'dist'
target will execute 'vcs-version.sh' and substitute the version string
into the tarball name, the README, and the 'configure.ac' script so that
users of the tarball will know what version the source code is from.
This is just a very simplified description of the autoconf toolflow. See
the GNU Autoconf documentation ('http://www.gnu.org/software/autoconf')
for more details on using these tools.
--------------------------------------------------------------------------
2.2. Basic Make Toolflow
--------------------------------------------------------------------------
To drive the actual build process the Automatic LaTeX Build System
leverages the ubiquitous 'make' tool. To use 'make', a user first
creates a 'Makefile' which contains a set of rules. Each rule specifies
a target file, a set of prerequisite files, and a command to generate
the target file from the prerequisites. The 'make' tool reads in a
makefile (usually named 'Makefile') and executes the appropriate
commands to build the document's PDF. When a user changes a subset of
the source files, 'make' determines which target files are out-of-date
based on the timestamps of the target and prerequisite files. 'make'
then runs the minimum number of commands to regenerate all out-of-date
targets, and thus efficiently rebuilds the project. A makefile can also
have non-file targets which act as aliases for a set of files to build
or commands to run. The Automatic LaTeX Build System requires the GNU
version of make since it uses several GNU make extensions. See the GNU
Make documentation ('http://www.gnu.org/software/make') for more details
on the 'make' tool.
Obviously writing a makefile from scratch for every new project is
undesirable. The Automatic LaTeX Build System provides a toplevel
makefile with most of the common make targets. For many projects, the
user will not need to make any changes to this toplevel 'Makefile'. So
the following commands will configure and build the project (assuming we
start in the root directory of the project).
> mkdir build
> cd build
> ../configure
> make
Note that we always build the project in a separate build directory to
keep the generated content separate from the original source content.
This makes it easy to do a clean build by just deleting the build
directory.
The default make target is to build the document PDF corresponding to
the toplevel LaTeX file in the 'src' subdirectory with the same name as
the project. For example, if the project is named 'foo', then the
default make target is to build 'foo.pdf' from 'src/foo.tex'. We can
also specify a desired target to build on the 'make' command line. For
example, to build the document 'foo.pdf' we use:
> make foo.pdf
To efficiently build LaTeX projects, it is important to track all of the
dependencies between the various input files. The build system includes
a custom script called 'mk-latex-deps.rb' (located in the 'scripts'
subdirectory) to scan LaTeX files and generate makefile fragments which
indicate which files any given toplevel document file depends on.
Currently the script scans for these macros:
- 'documentclass{class}'
- 'usepackage{package}'
- 'RequirePackage{package}'
- 'input{tex}'
- 'include{tex}'
- 'includegraphics{fig}'
- 'bibliography{bib1,bib2,...}'
So for example, if the toplevel LaTeX file named 'foo.tex' uses 'input'
to include 'bar' then 'mk-latex-deps.rb' will generate a makefile
fragment which specifies that 'foo.tex' depends on 'bar.tex'. The script
also recursively scans 'bar.tex' to see if there are any additional
dependencies on other input files. The script will also create
dependencies on class files if those files are in the 'src'
subdirectory. Use this script's '--help' command line option to find out
more information.
One of the challenges when building LaTeX projects is running the
various tools the right number of times to make sure that the final PDF
is up-to-date. For example, sometimes we need to run LaTeX once, then
run BibTeX, then run LaTeX two more times before our document is
up-to-date. Although we can always run all the tools, processing the
document multiple times can be slow. Most of the time we only need to
run LaTeX once. Trying to address this problem with just make scripting
is very difficult. So instead, the build system includes a custom script
called 'run-latex.rb' (located in the 'scripts' subdirectory) which
automatically figures out the minimum number of times we need to run
LaTeX and BibTeX to correctly generate the final PDF. This script also
allows a user to specify input directories which contain source files
and then it uses the 'TEXINPUTS' environment variable so that LaTeX
knows where to find these files. Use this script's '--help' command line
option to find out more information.
The toplevel makefile also includes several standard "non-file" targets.
Some of them are listed below:
- 'default' : build the default documents
- 'install' : install documents into prefix (e.g. top-level dir)
- 'prebuild' : prebuild files for all of the build system modules
- 'prebuild-mod' : prebuild files for the build system module 'mod'
- 'clean' : remove generated content (except autoconf files)
- 'clean-prebuild' : remove the prebuild directory
- 'dist' : make a source tarball
- 'distcheck' : make a source tarball, untar it, make doc, clean
- 'distclean' : remove everything
Sometimes, a user wants to have multiple documents as part of the same
LaTeX project. For example, we might want to have a version which
contains editorial comments and a separate version which does not. To
add extra toplevel LaTeX source files, the user will need to append
those files to either the 'default_doc_texs' or the 'extra_doc_texs'
variables in the toplevel 'Makefile.in'. Adding the files to
'default_doc_texs' means that these additional documents will be build
by default, while adding the files to 'extra_doc_texs' means that these
additional documents will only be built if the user explicitly specifies
them as a target on the 'make' command line.
The 'install' target will be default copy the final PDFs into the
toplevel directory. These copies can then be checked into subversion so
that users can view the most current version of the document (possibly
via an online repository browser) without having to build everything
from scratch.
--------------------------------------------------------------------------
2.3. Build System Modules
--------------------------------------------------------------------------
In addition to basic LaTeX source files and images, users often need
other kinds of input. For example, we might use the Inkscape drawing
program to create figures which we want to include in our document.
Inkscape generates 'svg' files so we will need to convert these into
'pdf' files for use with LaTeX. Similarly, we might want to include
Graphviz 'dot' files, Python plots, or XFig 'fig' files in our document.
All of these file formats need to be converted into something which
LaTeX can handle (usually PDF). Ideally, we want to add Autoconf checks
to see if the required conversion tools are installed and Makefile rules
to automatically convert these various file formats. Modifying the
toplevel 'configure.ac' and 'Makefile.in' for each file type results a
very monolithic build system. To address this, the Automatic LaTeX Build
System includes support for "modules".
Modules are subdirectories in the toplevel project which include various
script fragments and all of the related input files. For example, a
'svg' module responsible for converting 'svg' files to PDF is included
with the build system by default. Module names should be short, all
lower-case, and describe the type of file handled by the module. A user
needs to specify which modules are included in the project in the
toplevel 'configure.ac' file using the 'ALBS_MODULES' macro. After
changing 'configure.ac', you will need to rerun 'autoconf' in the
toplevel project directory.
Each module is a self-contained subdirectory in the project which
includes an autoconf fragment (eg. 'svg/svg.ac'), a makefile fragment
(eg. 'svg/svg.mk.in'), a LaTeX package (eg. 'svg/svg.sty'), and all the
input files (eg. 'svg/*.svg'). Users can put checks for the various
conversion tools (eg. 'inkscape' and 'epstopdf') in the autoconf
fragment, and they can include makefile rules which specify how to
actually do the conversion in the makefile fragment. The LaTeX package
can help setup the LaTeX environment for use with the module.
Currently there are two modules included with the basic ALBS template.
The 'svg' module manages converting SVG figures to PDF and the 'py'
module manages creating plots by running Python scripts automatically.
For the 'svg' module, simply create your SVG file (eg. 'figure.svg') and
place it in the 'svg' subdirectory and then use the
'includegraphics{figure.svg.pdf}' macro. The build system will
automatically run 'inkscape' to generate a PDF file. You can also use the
'scripts/svg-split-layers.rb' script to create multiple PDFs from the
same SVG file with different layers in each PDF. This is particularly
useful for Beamer presentations. Consult the 'svg.mk.in' make fragment
for more information. For the 'py' module, create a Python script which
generates the desired plot as a pdf (eg. 'plot-foo.py') and then use the
'includegraphics' macro to include 'plot-foo.py.pdf'. The build system
will automatically run the 'plot-foo.py' script and also take care of
cropping and embedding the fonts for the resulting PDF file.