Title Page: Using Automake in the Groff project
Contents
Using Automake in the Groff project
1. Overview, the initial build
1.1. First build
1.2. Automake in the autotools process
1.3. Modification of autotools files
2. Building a program
2.1. A program and its source files
2.2. Linking against a library
2.3. Preprocessor flags
2.4. Cleaning
2.5. Dependencies
2.6. Scripts
3. Non-recursive make schema
3.1. 1st possibility: make recursion
3.2. Non-recursive make used by the Groff project
4. Installing data
4.1. A simple case
4.2. Dealing with generated files
5. Extending Automake's rules
5.1. Local clean rules
5.2. Local install/uninstall rules and hooks
Using A
utomake in the Gr
off pr
oject
by
Bertrand Garrigues
©2014, 2017 Free Software F
oundation
Contents
1. Overvie
w
, the initial b
uild
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.1. F
irst b
uild
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1.2. A
utomake in the autotools pr
ocess
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
1.3. Modif
ication of autotools f
iles
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2. Building a program
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
2.1. A pr
ogr
am and its sour
ce f
iles
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
2.2. Linking against a libr
ary
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
2.3. Pr
epr
ocessor flags
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
2.4.
Cleaning
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
2.5.
Dependencies
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
2.6.
Scripts
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
3. Non-recursi
ve mak
e schema
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
3.1. 1st possibility: make r
ecursion
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
3.2. Non-r
ecursive mak
e used by the Gr
of
f pr
oject
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
4. Installing data
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
4.1. A simple case
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
4.2. Dealing with gener
ated f
iles
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
5. Extending Automake’s rules
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
5.1. Local clean rules
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
5.2. Local install/uninstall rules and hooks
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
-
i
-
Using A
utomake in the Gr
off pr
oject
by
Bertrand Garrigues
This
is
a
quick
ov
ervie
w
of
ho
w
to
use
‘automake’
in
the
grof
f
project,
and
is
intended
to
help
the
de
velopers
and
contrib
utors
f
ind
their
way
when
they
ha
ve
to
make
changes
to
the
sources files or to
the data
that are
installed. If
you need
more details
on ‘automake’, here
are
some reading suggestions:
•
The Automake Manual:
https://www
.gnu.or
g/software/automak
e/manual/automake.html
•
A book by John Calcote, with good practical examples:
http://fsmsh.com/2753
•
This site, by Diego Petteno, with good practical e
xamples too:
https://autotools.io/index.html
1. Over
view
, the initial b
uild
1.1. First b
uild
Grof
f
integrates
the
‘gnulib’
and
uses
its
‘bootstrap’
script.
When
compiling
from
the
git
repository
, you should f
irst in
v
oke this script:
$ ./bootstrap
This will:
•
Clone the gnulib repository as a git submodule in ‘gnulib’, add the needed gnulib sources
f
iles in ‘lib’, add the needed gnulib m4 macros in ‘gnulib_m4’.
•
In
v
oke autoreconf that will call all the ‘GNU autotools’
(‘aclocal’, ‘autoheader’,
‘autoconf’, ‘automake’) in the right order for creating the follo
wing f
iles:
–
INST
ALL (a symlink to gnulib’s INST
ALL f
ile)
–
Makef
ile.in
–
aclocal.m4
–
autom4te.cache/
–
b
uild-aux/ (that contains all the helper scripts)
–
conf
igure
–
src/include/conf
ig.hin
T
h
e
f
i
l
e
a
c
l
o
c
a
l
.
m
4
i
s
g
e
n
e
r
a
t
e
d
a
n
d
t
h
e
g
r
o
ff
m
4
m
a
c
r
o
s
a
r
e
i
n
c
l
u
d
e
d
v
i
a
t
h
e
a
c
i
n
c
l
u
d
e
.
m
4
f
i
l
e
.
At
this
point
you
can
in
v
oke
the
‘conf
igure’
script
and
call
‘make’
to
b
uild
the
grof
f
-
1
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
project. Y
ou can do it in the source tree:
$ ./configure
$ make
Y
ou can also b
uild grof
f in an out-of-source b
uild tree, which is cleaner:
$ mkdir build
$ cd build
$ ../configure
$ make
Parallel
b
uild
is
also
supported:
‘make’
can
be
in
v
oked
with
the
-j
option,
which
will
greatly
speed up the b
uild.
1.2. A
utomake in the autotools pr
ocess
Automake’s
main
job
is
to
generate
a
Makef
ile.in
f
ile
(this
f
ile
is
maintained
manually
on
projects using
only autoconf).
The main
f
ile processed
by ‘automake’
is the
Makef
ile.am file,
which e
ventually generates a Mak
ef
ile. The (simplif
ied) process is:
•
‘aclocal’
generates
the
‘aclocal.m4’
f
ile
from
‘conf
igure.ac’
and
the
user
-def
ined
macros
in ‘acinclude.m4’.
•
‘autoheader’
generates
conf
ig.h.in.
•
‘autoconf’
generates
the
‘conf
igure’
script
from
‘aclocal.m4’
and
‘conf
igure.ac’
•
‘automake’
generates
Makef
ile.in
from
Makef
ile.am
and
the
‘conf
igure.ac’
f
ile.
It
also
generates some helper scripts, on the grof
f project they are located in b
uild-aux.
•
‘conf
igure’
generates
‘conf
ig.status’
•
‘conf
ig.status’
generates
the
Makef
ile
and
conf
ig.h.
Fi
na
ll
y
,
‘a
ut
or
ec
on
f’
is
th
e
pr
og
ra
m
th
at
ca
n
be
us
ed
to
ca
ll
th
es
e
v
ar
io
us
to
ol
s
in
th
e
co
rr
ec
t
or
de
r
.
Automake
def
ines
a
set
of
special
v
ariables
that
are
used
to
generate
v
arious
b
uild
rules
in
the
f
inal
Makef
ile.
Note
ho
we
ver
that
if
Automake’s
predef
ined
rules
are
not
enough,
you
still
ha
ve the
possibility
of
adding
handwritten
standard
‘make’
rules
in
a
Makef
ile.am;
these
rules will be copied verbatim in the Mak
ef
ile.in and then in the f
inal Makef
ile.
1.3. Modif
ication of autotools f
iles
Pre
viously
,
when
grof
f
used
‘autoconf’
only
and
not
‘automake’, you
had
to
in
v
oke manually
the autotools,
depending on
what you
modif
ied. For example, to
change the
f
ile ‘aclocal.m4’,
you
had
to
run
the
shell
command
‘aclocal
-I
m4’;
to
recreate
the
f
iles
‘conf
igure’
and
‘Makef
ile’, you had to use the command ’autoreconf - I m4’.
No
w
,
as
grof
f
uses
‘automake’,
you
don’t
need
to
run
‘autoreconf’.
If
you
make
some
changes
in
Makef
ile.am
or
conf
igure.ac,
all
the
f
iles
that
need
to
be
updated
will
be
-
2
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
regenerated when you e
xecute ‘mak
e’.
2. Building a pr
ogram
2.1. A pr
ogram and its sour
ce f
iles
Generally
speaking,
when
using
‘automake’
you
will
ha
ve
to
write
a
Makef
ile.am
f
ile
and
use
the
v
ariable
bin_PROGRAMS
to
declare
a
program
that
should
be
b
uilt,
and
then
list
the
sources of
this program
in a
v
ariable that
starts with
the name
of your
program and
ends with
_SOURCES
.
In
the
grof
f
project
we
ha
ve
only
1
top-le
vel
Makef
ile.am
that
includes
se
veral
.am f
iles.
T
ake
for
example
the
b
uild
of
grolbp,
in
src/de
vices/grolbp/grolbp.am.
The
f
ile
starts
with:
bin_PROGRAMS += grolbp
This
says
that
a
program
named
‘grolbp’
is
added
to
the
list
of
the
programs
that
should
be
b
uilt.
The
v
ariable
bin_PROGRAMS
is
initialized
to
an
empty
string
in
the
top-le
vel
Makef
ile.am,
which
includes
grolbp.am.
(W
e
will
see
later
why
we
don’t
write
directly
bin_PROGRAMS = grolbp
in a Makef
ile.am in the grolbp directory
.)
Then, we list the sources of grolbp like this:
grolbp_SOURCES = \
src/devices/grolbp/lbp.cpp \
src/devices/grolbp/lbp.h \
src/devices/grolbp/charset.h
As
you
added
‘grolbp’
to
bin_PROGRAMS
,
you
need
to
def
ine
the
sources
of
grolbp
in
the
v
ariable
grolbp_SOURCES
.
If
you
write
in
another
f
ile
bin_PROGRAMS
+=
foo
you
will list the sources of ‘foo’
in
foo_SOURCES
.
W
ith
these
two
statements,
the
resulting
generated
Makef
ile
will
contain
e
verything that
is needed
to build, clean,
install and
uninstall the
‘grolbp’
binary when
in
v
oking the
adequate
‘make’
command.
Also,
the
source
f
iles
listed
in
grolbp_SOURCES
will
automatically
be
included
in
the
distrib
ution
tarball.
That
is
why
the
headers
are
also
listed
in
grolbp_SOURCES
:
it
is
not
necessary
to
add
them
in
order
to
correctly
b
uild
‘grolbp’,
b
ut
this way the headers will be distrib
uted.
•
The path to the f
iles are relati
ve to the top-le
vel directory
.
•
The binaries are generated in the top-le
vel b
uild directory
.
•
The .o f
iles are generated in the directory where the source f
iles are located, or
, in the
case of an out-of-source b
uild tree, in a directory that is the replication of the source tree
directory
. For e
xample if you b
uilt grof
f in a ‘b
uild’
directory
, lbp.o (object f
ile from src/
de
vices/grolbp/lbp.cpp) will be located in b
uild/src/de
vices/grolbp/lbp.o.
-
3
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
W
e will also see later the reasons; this is due to the non-recursi
ve mak
e design.
2.2. Linking against a library
T
o list which libraries grolbp needs to link against, we just write:
grolbp_LDADD = $(LIBM) \
libdriver.a \
libgroff.a \
lib/libgnu.a
Again,
we
use
the
v
ariable
grolbp_LDADD
because
we
added
a
program
named
‘grolbp’.
This
will
also
automatically
set
b
uild
dependencies
between
‘grolbp’
and
the
libraries
it
needs:
‘libdri
ver
.a’
and
‘libgrof
f.a’,
that
are
con
venience
libraries
b
uilt
within
the
grof
f
project, will be compiled before grolbp.
2.3. Pr
epr
ocessor flags
Preprocessor
flags
that
are
common
to
all
the
binaries
are
listed
in
the
v
ariable
AM_CPPFLAGS
in
the
top-le
vel
Makef
ile.am.
If
a
‘foo’
binary
needs
specif
ic
preprocessor
flags,
use
foo_CPPFLAGS
,
for
example,
in
src/de
vices/xditvie
w/xditvie
w
.am,
extra
flags
are needed to b
uild gxditvie
w and are added like this:
gxditview_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) -Dlint \
-I$(top_builddir)/src/devices/xditview
The use
of specific CPPFLA
GS changes
the name
of the
generated objects:
the .o
object
f
iles are
pref
ixed with the name
of the
program. For example, the .o file corresponding to
src/
de
vices/xditvie
w/de
vice.c will be src/de
vices/xditvie
w/gxditvie
w-de
vice.o.
2.4.
Cleaning
Y
ou
don’t
need
to
write
rules
to
clean
the
programs
listed
in
bin_PROGRAMS
,
‘automake’
will
write
them
for
you.
Ho
we
ver
,
some
programs
might
ha
ve
generated
sources
that
should
be
cleaned.
In
this
case,
you
ha
ve
mainly
two
special
v
ariables
to
list
extra
f
iles
that
should
be cleaned:
•
MOSTLYCLEANFILES
for f
iles that should be cleaned by ‘make mostlyclean’
•
CLEANFILES
for f
iles that should be cleaned by ‘make clean’
There is also the possibility of writing custom rules. W
e will see that later
.
2.5.
Dependencies
W
e
ha
ve
already
seen
that
when
linking
against
a
con
venience
library
,
the
dependencies
are
already created by ‘automake’. Ho
we
ver
, some dependencies still need to
be manually added,
for
example when
a
source
f
ile
includes
a
generated
header
.
In
this
case,
the
easiest
way is
to
-
4
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
add
a
plain-make
dependency
.
For
example,
src/rof
f/grof
f/grof
f.cpp
includes
defs.h,
which
is
a generated header
. W
e just add in src/rof
f/grof
f/grof
f.am:
src/roff/groff/groff.$(OBJEXT): defs.h
2.6.
Scripts
Apart
from
bin_PROGRAMS
,
there
is
another
similar
special
v
ariable
for
scripts:
bin_SCRIPTS
.
The
scripts
listed
in
this
v
ariable
will
automatically
be
b
uilt
(of
course
you
ha
ve to
provide your
custom
rule
to
b
uild
the
script),
installed
and
uninstalled
when
in
v
oking
‘make’,
‘make
install’
and
‘make
uninstall’.
The
main
dif
ference
is
that
unlike
the
programs
listed in
bin_PROGRAMS
, the scripts will
not be cleaned by
default. The
y are not distributed
by
default
either
.
In
the
grof
f
project,
bin_SCRIPTS
are
cleaned
because
they
are
added
to
MOSTLYCLEANFILES
in the top-le
vel Mak
ef
ile.am.
A simple example are the gropdf and pdfmom scripts in src/de
vices/gropdf/gropdf.am:
bin_SCRIPTS += gropdf pdfmom
[...]
gropdf: $(gropdf_dir)/gropdf.pl $(SH_DEPS_SED_SCRIPT)
$(AM_V_GEN)$(RM) $@ \
sed -f $(SH_DEPS_SED_SCRIPT) \
-e "s|[@]VERSION[@]|$(VERSION)|"
\
-e "s|[@]PERL[@]|$(PERL)|"
\
-e "s|[@]GROFF_FONT_DIR[@]|$(fontpath)|"
\
-e "s|[@]RT_SEP[@]|$(RT_SEP)|"
$(gropdf_dir)/gropdf.pl \
>$@
&&
chmod
+x
$@
pdfmom: $(gropdf_dir)/pdfmom.pl $(SH_DEPS_SED_SCRIPT)
$(AM_V_GEN)$(RM) $@ \
sed -f $(SH_DEPS_SED_SCRIPT) \
-e "s|[@]VERSION[@]|$(VERSION)|"
\
-e "s|[@]RT_SEP[@]|$(RT_SEP)|"
\
-e "s|[@]PERL[@]|$(PERL)|"
$(gropdf_dir)/pdfmom.pl \
>$@
&& chmod +x $@
In
this
example, the
‘@'
symbol
is
protected
by
square
brackets
to
pre
vent the
substitution
of
the v
ariable by ‘automake'.
3. Non-r
ecursiv
e make schema
There
are
two
possibilities
for
or
ganizing
the
Makef
ile.am
of
a
lar
ge
project,
using
a
recursi
ve or a non-recursi
ve ‘mak
e'.
-
5
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
3.1. 1st possibility: make r
ecursion
A
top
le
vel
Makef
ile.am
includes
another
Makef
ile.am,
using
the
SUBDIRS
directi
ve,
and
the
Makef
ile.am
of
each
sub-directory
lists
the
programs
that
should
be
b
uilt.
If
we
had
chosen
this
type
of
or
ganization,
we
would
ha
ve
a
Makef
ile.am
in
src/de
vices/grolbp
and
in
each
directory
that
contain
sources
to
b
uild
a
program
(tbl,
eqn,
trof
f,
and
so
on).
W
e
would
write in the top-le
vel Mak
ef
ile.am:
SUBDIRS = src/devices/grolbp \
... (and all the dir that build a program or a script)
and in src/de
vices/grolbp, we would ha
ve a f
ile Makef
ile.am that contains:
bin_PROGRAMS = grolbp
grolbp_SOURCES = lbp.cpp lbp.h charset.h
Only
‘grolbp’
is
af
fected
to
the
v
ariable
bin_PROGRAMS
.
It
would be
the
same
in,
say
,
src/rof
f/trof
f:
you
would
ha
ve
a
Makef
ile.am
with
bin_PROGRAMS
=
troff
.
W
e
would
ha
ve
one
generated
Makef
ile
per
Makef
ile.am
f
ile:
in
the
b
uild
tree
you
will
ha
ve
the
top-
le
vel
Makef
ile,
grolbp’s
Makef
ile
in
src/de
vices/grolbp,
trof
f’s
Makef
ile
in
src/rof
f/trof
f,
and
so
on.
When
calling
‘make’
to
b
uild
e
verything,
‘make’
will
be
recursi
vely
called
in
all
the
directories
that
ha
ve
a
Makef
ile.
Thus,
the
paths
are
logically
relati
ve
to
the
directory
that
contains the Makef
ile.am.
This
approach
has
the
disadv
antage
of
making
dependencies
harder
to
resolve:
each
Makef
ile does not kno
w the tar
gets of the other Makef
iles. It also makes the b
uild slo
wer
.
3.2. Non-r
ecursiv
e make used by the Gr
off pr
oject
The second possibility
, which was chosen for the grof
f project, is to use a non-recursi
ve mak
e
schema.
It
is
described
in
paragraph
7.3
of
the
Automake manual
(“An
Alternati
ve Approach
to
Subdirectories”),
based
on
the
follo
wing
paper
from
Peter
Miller:
Recursive
Make
Consider
ed Harmful
.
The
idea
is
to
ha
ve
a
single
Makef
ile
that
contains
all
the
rules.
That
is
why
we
ha
ve
only
a
single
Makef
ile.am
in
the
top-le
vel
directory
which
includes
all
the
.am
f
iles
that
def
ine
rules
to
b
uild
the
v
arious
programs.
The
inclusion
is
done
with
the
include
directi
ve, not
SUBDIRS
. Using
‘include’
is like
copying the
contents of
the included
f
ile into
the top-le
vel Mak
ef
ile.am, and will not generate other Makef
ile.
W
e f
irst say in this top-le
vel Mak
ef
ile.am:
bin_PROGAMS =
and
then
all
the
.am
f
iles
that
def
ine
a
program
to
be
b
uilt
(e.g.
src/de
vices/grolbp/grolbp.am,
src/rof
f/trof
f/trof
f.am,
and
so
on)
ov
erload
this
v
ariable,
so
that
at
the
end,
all
the
programs
that should be built are listed in this
bin_PROGRAMS
v
ariable. This is the reason why all the
paths
in
the
v
arious
.am
f
iles
are
relati
ve
to
the
top-le
vel
directory:
at
the
end
we
will
ha
ve
-
6
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
only one Makef
ile in the top-le
vel directory of the b
uild tree.
As
the
resulting
single
Makef
ile
kno
ws
all
the
tar
gets,
the
dependencies
are
easier
to
manage.
The
b
uild
is
also
faster
,
particularly
when
compiling
a
single
f
ile:
‘make’
is
called
once only
and the
f
ile will
be instantly
reb
uilt, while
on a
recursi
ve make system, ‘make’
will
ha
ve to be in
v
oked in all the sub-directories.
Note
also
that
in
order
to
make
‘gnulib’
work
with
this
non-recursi
ve
schema,
the
‘--automake-subdir’
conf
iguration
should
be
selected
in
bootstrap.conf.
4. Installing data
V
ariables
that
end
with
_DATA
are
special
v
ariables
used
to
list
f
iles
that
should
be
installed
in
a
particular
location.
The
pref
ix
of
the
v
ariables
should
refer
to
another
pre
viously
def
ined
v
ariable
that
ends
with
a
‘dir’
suf
f
ix.
This
v
ariable
that
ends
with
‘dir’
def
ines
where
the
f
iles
should be installed.
4.1. A simple case
For e
xample, in font/de
vX100/de
vX100.am, we can see this:
if !WITHOUT_X11
devX100fontdir = $(fontdir)/devX100
devX100font_DATA = $(DEVX100FONTS)
endif
EXTRA_DIST += $(DEVX100FONTS)
DEVX100FONTS
is
just
a
list
of
font
f
iles,
def
ined
at
the
beginning
of
de
vX100.am.
fontdir
is
where
all
the
font
directories
are
installed,
it
is
def
ined
in
the
top-le
vel
Makef
ile.am.
The
conditional
if
!WITHOUT_X11
is
used
to
pre
vent
the
installation
of
these
f
iles
if
X11
is
not
a
v
ailable.
W
e f
irst def
ine where we wants to install the de
vX100 fonts with:
devX100fontdir = $(fontdir)/devX100
Because
we
declared
a
v
ariable
ending
with
‘dir’,
we
are
allo
wed
to
def
ine
devX100font_DATA
(you
remov
e
the
‘dir’
suf
f
ix
and
add
_DATA
).
W
ildcards
are
not
supported in the special v
ariables that end with
_DATA
.
W
ith
these
two
lines,
‘make
install’
will
install
the
f
iles
listed
in
DEVX100FONTS
and
‘make
uninstall’
will
uninstall
them.
devX100fontdir
will
be
automatically
created
if
missing
during
the
installation
process,
b
ut
not
remov
ed
during
the
uninstall.
The
complete
fontdir
is remov
ed by a custom uninstall rule (uninstall_grof
fdirs in Makef
ile.am).
Because
the
f
iles
listed
in
devX100font_DATA
are
not
distrib
uted
by
default,
we
explicitly
added
them
to
the
EXTRA_DIST
v
ariable,
which
lists
all
the
f
iles
that
should
be
distrib
uted and that are not taken into account by the def
ault automake rules.
-
7
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
EXTRA_DIST += $(DEVX100FONTS)
Another
possibility
would
ha
ve
been
to
add
a
‘dist’
pref
ix
to
the
devX100font_DATA
v
ariable, in this
case the use
of
EXTRA_DIST
is useless
(except of course if
WITHOUT_X11
is true, in this case we don’t install the f
iles b
ut we still ha
ve to distrib
ute them):
if !WITHOUT_X11
devX100fontdir = $(fontdir)/devX100
dist_devX100font_DATA = $(DEVX100FONTS)
else
EXTRA_DIST += $(DEVX100FONTS)
endif
4.2. Dealing with generated f
iles
In
the
pre
vious
example,
all
the
font
f
iles
that
must
be
installed
were
already
present
in
the
source
tree.
But
in
some
cases,
you
need
to
generate
the
f
iles
you
intend
to
install.
In
this
case,
the
f
iles
should
be
installed
b
ut
not
distrib
uted.
A
simple
way to
deal
with
this
is
to
add
a ‘nodist’
pref
ix to your
xxx_DATA
v
ariable.
For
example
in
font/de
vps/de
vps.am,
we
ha
ve
a
list
of
font
f
iles
already
present
in
the
source
tree,
def
ined
by
DEVPSFONTFILES
,
and
another
list
of
font
f
iles
that
are
generated,
listed
in
the
v
ariable
DEVPSFONTFILES_GENERATED
.
They
should
all
by
installed
in
a
‘de
vps’
directory
under
the
fontdir
.
Thus
the
follo
wing
three
lines,
where
we
use
the
‘dist’
and ‘nodist’
pref
ixes:
devpsfontdir = $(fontdir)/devps
dist_devpsfont_DATA = $(DEVPSFONTFILES)
nodist_devpsfont_DATA = $(DEVPSFONTFILES_GENERATED)
The generated f
iles are not cleaned by default, thus we add:
MOSTLYCLEANFILES += $(DEVPSFONTFILES_GENERATED)
5. Extending A
utomake’s rules
5.1. Local clean rules
In
most
of
the
cases,
the
f
iles
that
need
to
be
cleaned
are
automatically
determined
by
‘automake’, or were
added to
the
MOSTCLEANFILES
or
CLEANFILES
variables. Ho
we
ver
,
you
might
need
to
def
ine
a
specif
ic
rule
to
clean
some
f
iles
that
were
not
added
to
any
list.
Automake def
ines a set of targets to extend the clean tar
gets with your own rules: clean-local,
mostlyclean-local,
distclean-local
or
maintainerclean-local.
An
example
of
such
extension
exists in
font/de
vpdf/de
vpdf.am:
because
some
fonts
are
not
explicitly listed
in
a
xxx_DATA
-
8
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
v
ariable
b
ut
generated
by
a
custom
rule,
we
def
ine
an
extra
rule
to
extend
the
‘mostlyclean’
tar
get:
mostlyclean-local: mostlyclean_devpdf_extra
mostlyclean_devpdf_extra:
@echo Cleaning font/devpdf
rm -rf $(top_builddir)/font/devpdf/enc \
$(top_builddir)/font/devpdf/map;
if test -d $(top_builddir)/font/devpdf; then \
for f in $(GROFF_FONT_FILES); do \
rm -f $(top_builddir)/font/devpdf/$$f; \
done; \
fi
5.2. Local install/uninstall rules and hooks
Similarly
to
the
clean
rules,
there
are
extensions
to
install
and
uninstall
rules.
They
come
with two fla
v
ous, local rules and hooks.
•
There are 2 rules to extend install commands: ‘install-e
xec-local’
for binaries and
‘install-data-local’
for
data.
•
There is 1 uninstall local rule: ‘uninstall-local’.
There are
no guarantees
on the
order of
ex
ecution of
these local
rules. An
example of local
rule
is
the
installation
of
GXditvie
w
.ad
and
GXditvie
w-color
.ad
f
iles
in
src/de
vices/
xditvie
w/xditvie
w
.am:
if
these
f
iles
are
already
installed,
the
old
f
iles
are
f
irst
sa
ved.
Also,
the
f
inal
f
ile
that
is
installed
is
stripped
from
its
.ad
suf
f
ix.
Thus
the
usage
of
a
custom
rule
rather than the def
inition of a
xxx_DATA
v
ariable:
# Custom installation of GXditview.ad and GXditview-color.ad
install-data-local: install_xditview
uninstall-local: uninstall_xditview
[...]
install_xditview: $(xditview_srcdir)/GXditview.ad
-test -d $(DESTDIR)$(appdefdir) \
|| $(mkinstalldirs) $(DESTDIR)$(appdefdir)
if test -f $(DESTDIR)$(appdefdir)/GXditview; then \
mv $(DESTDIR)$(appdefdir)/GXditview \
$(DESTDIR)$(appdefdir)/GXditview.old; \
fi
[...]
$(INSTALL_DATA) $(xditview_srcdir)/GXditview.ad \
-
9
-
Bertrand Garrigues
USING A
UTOMAKE IN THE GR
OFF PR
OJECT
$(DESTDIR)$(appdefdir)/GXditview
Hooks,
on
the
other
hand,
are
guaranteed
to
be
ex
ecuted
after
all
the
standard
tar
gets
ha
ve been e
xecuted.
•
There are 2 install hooks: ‘install-ex
ec-hook’
and ‘install-data-hook’.
•
There is 1 uninstall hook: ‘unintall-hook’
An
example
of
hook
is
the
‘uninstall_grof
fdirs’
rule
in
the
top-le
vel
Makef
ile.am.
This
hook
is
used
to
remov
e
all
the
directories
specif
ic
to
grof
f
introduced
by
the
installation
process.
Obviously
it
could
not
be
a
local
extension
of
‘uninstall’
because
the
order of ex
ecution is not guaranteed.
# directories specific to groff
uninstall-hook: uninstall_groffdirs
uninstall_groffdirs:
if test -d $(DESTDIR)$(datasubdir); then \
rm -rf $(DESTDIR)$(fontdir); \
rm -rf $(DESTDIR)$(oldfontdir); \
rmdir $(DESTDIR)$(datasubdir); \
fi
[...]
-
10
-