The most typical use of autoconf is to configure a file
Makefile.in. You can write this yourself, as
described in the discussion of
autoconf, but since so much of a typical makefile
is boilerplate, automake exists to write this boilerplate
for you. This has the additional advantage that we can
support and enforce Starlink-specific conventions with a
customised installation of automake. We (currently) use
an adapted version of automake -- see automake
--version for the version number, and Appendix B for a summary of the differences.
The file which controls automake is
Makefile.am.
Automake reads both this file and
configure.ac, and based on these emits a
Makefile.in. It is this latter file which
you distribute, and which is substituted at build time by the
./configure script which autoconf generates
in turn.
The resulting Makefile has rules to do all
the required building and installation in a very portable
fashion, as well as targets to make distributions
(make dist), do tests (make
check), clean up (make clean,
make distclean and make
maintainer-clean) and, in the case of Starlink
automake, do an install along with an installation
manifest.
The Makefile.am script consists, in its
simplest form, of a sequence of declarations of the
relationships between the source files in your
distribution and the programs and libraries they are
intended to produce. For example, here is the
Makefile.am for the PAR library, slightly edited:
## Process this file with automake to produce Makefile.in
lib_LTLIBRARIES = libpar_adam.la
libpar_adam_la_SOURCES = $(F_ROUTINES)
include_HEADERS = $(PUBLIC_INCLUDES)
F_ROUTINES = \
par1_menu.f \
par_cancl.f \
[blah...]
PUBLIC_INCLUDES = \
PAR_ERR \
PAR_PAR \
par.h \
parwrap.h \
par_err.h \
par_par.h
BUILT_SOURCES = PAR_ERR par_err.h
Overall, you can see that this automake source file is
syntactically a makefile -- the statements in this example
look like makefile variable settings, and it is possible
to put makefile rules in the Makefile.am
file, though that is not illustrated here. This is
slightly deceptive, however, and while it was useful to
think, above, of the configure.ac file as
being the template of the eventual
./configure script, for automake you should
think of the match between the input syntax and the
makefile as a happy coincidence. You provide information
to automake through the Makefile.am file,
and based on that it then emits the Makefile.in it
thinks you want (or need, at least).
The first line is a conventional comment. It starts with
a doubled hash mark ##, which causes automake
to discard the text after it; lines beginning with a
single comment character are copied verbatim into the
generated Makefile.in.
The next stanza declares that there is to be a library
libpar_adam.la, and that the sources for this
file are in the `makefile variable'
F_ROUTINES.
Though the variables F_ROUTINES and
PUBLIC_INCLUDES are specific to this
makefile, and arbitrary, the other variable names have both
structure and meaning for automake.
The variable lib_LTLIBRARIES consists of the
`prefix' lib and the `primary'
LTLIBRARIES. The primary tells automake that
you wish to build the libtool library
libpar_adam.la, and the prefix indicates that
this is to be installed with the other libraries (the
variable pkglib_LTLIBRARIES, for example, would tell
automake that you wanted to install the result in a
package-specific library). For each of the libraries
listed in this variable, separated by spaces, there must
be a corresponding _SOURCES variable, which
has the `primary' SOURCES and a prefix
formed from the library name, which lists
the set of source files for that library.
The prefix must be canonicalised by replacing
with underscores everything other than letters and numbers.
As well as declaring the files which are to be compiled
into the library, this
indicates to automake that these source files are to be
distributed as part of the final tarball, and that it must
emit makefile rules to install the library in the correct
place, with the correct installation commands.
For the list of such associated primaries, see section Program and Library Variables of the automake
documentation.
By default, libtool builds both static and shared
libraries. You can control
this if necessary with the --enable-shared
and --disable-shared
options to ./configure, and with the
AC_DISABLE_SHARED autoconf variable. For
further details see the
documentation for AC_PROG_LIBTOOL in the
Libtool manual.
If we only wanted to build static libraries, we would
replace this line with lib_LIBRARIES =
libpar_adam.a, and the given library would be
built in the usual way, without involving libtool.
The LIBRARIES and LTLIBRARIES
primaries can have any one of the prefixes
libdir, pkglibdir,
check or noinst, with the latter
indicating that the library should be built but not
installed. Having non-installed libraries can be useful
when you are building a library conditionally, or in stages.
Libtool refers to these as `convenience libraries', and they
are discussed in section Libtool Convenience Libraries of the automake
manual.
The other very important primary (not shown here) is
PROGRAMS, which describes programs which are to
be built and installed (the special Starlink case of
monoliths is described below). This can have the prefixes
bin, sbin, libexec,
pkglib, check or
noinst: check is for tests, and is
described in Section 4.4;
noinst indicates that the program should be
built but not installed, and is useful for programs which
are used during the build -- for generating header files for
example -- but which are not part of the final product.
There is no single standard list of prefixes, since each
primary supports only a subset of them (you cannot declare
bin_LIBRARIES, for example), but several are
mentioned in automake's What Gets
Installed, and the directories in question are
discussed in autoconf's 4.7.2 Installation
Directory Variables.
The include_HEADERS line is similar: it
indicates that the listed files are to be distributed, and
are to be installed in the correct place for include
files.
The final line which is significant to automake is the
BUILT_SOURCES
line. This says that, even
though PAR_ERR and par_err.h are
to be installed and distributed, they are not actually
genuine source files, but must be built; adding the
BUILT_SOURCES line forces automake to add a
dependency for these files at an artificially early stage.
It is only rather rarely
necessary to include a line like this. If one of the
source files were in this category, then it would
naturally be built when it was required, without any
need to add it to BUILT_SOURCES. As it happens,
there is no rule in this file for building these targets;
that is added automatically by automake when it spots that
the STAR_MESSGEN macro has been used in the
configure.ac file which partners this
Makefile.am. In a more general case,
however, you would add a make-style rule to the
Makefile.am file to build these files from
their (presumably undistributed) sources. See also Built sources in
the automake manual.
For a second example, we can look at the
Makefile.am for the sst
application (this is a non-distributed application for
building documentation).
## Process this file with automake to produce Makefile.in
bin_SCRIPTS = start
bin_MONOLITHS = sst_mon
sst_mon_SOURCES = \
sst_mon.f \
$(sst_mon_TASKS:=.f) \
$(SUBSRC) \
$(SUBCSRC) \
$(PRIVATE_INCLUDES)
sst_mon_TASKS = forstats procvt prohlp prolat propak prohtml
sst_mon_LDADD = $(LDADD) `fio_link`
SUBSRC = sst_clean.f sst_fwild.f sst_latex.f sst_puts.f sst_trcvt.f \
sst_cntac.f sst_get.f sst_latp.f sst_rdad1.f sst_trhlp.f \
[blah...]
SUBCSRC = find_file.c
PRIVATE_INCLUDES = SST_PAR SST_SCB
# special installation directory (but see discussion below)
sstsupportdir = $(bindir)
sstsupport_DATA = sun.tex sst.tex layout.tex forstats.dat html.sty
# The `start' script needs to have installation locations edited into it
edit = sed \
-e 's,@bindir\@,$(bindir),g' \
-e 's,@VERSION\@,$(VERSION),g'
start: start.in
rm -f start.tmp start
$(edit) \
-e 's,@edited_input\@,start: produced from start.in by Makefile.am,' \
$(srcdir)/start.in >start.tmp
mv start.tmp start
EXTRA_DIST = start.in $(sstsupport_DATA)
This makefile configures and installs a script, builds and installs a monolith, and adds some supporting data files in a non-standard place.
The SCRIPTS primary indicates to automake
where and how to install the start script.
The start script must be generated, since it
is to include the version number and installation
location. Since it includes the installation location, it
should not be generated at configure time or
install time, but instead at make time, so that the user
is free to specify one installation prefix at configure time
(through ./configure --prefix=www), override
this with another prefix at build time (through
make prefix=xxx) and specify a
different one -- presumably a staging location or
something similar -- at installation time (through
make prefix=yyy install). It is the prefix at
build time that is to be baked into the code, if
any such baking has to be done. This is one of the GNU
conventions mentioned in Section 2.1, and is
discussed in a little more detail in section
4.7.2
Installation Directory Variables of the autoconf
manual. This is why we have to include a makefile-style
rule for deriving the file start from its
template start.in. This substitutes in the
values of the makefile variables bindir and
VERSION; these get their values, in the
resulting Makefile, by having those values
substituted in to the generated Makefile.in
by the generated ./configure script; the
careful escaping of the @-signs in the sed command is to
match the @...@ in start.in
while not matching this in
Makefile.am or the resulting
Makefile.in (yes, this can get a little
confusing).
This Makefile.am also declares a single
monolith (this and the TASKS primary below
are obviously part of the Starlink extensions to automake)
and its associated SOURCES, along with its
component tasks. For fuller details of the monoliths
support, see Section 3.4. This incidentally
illustrates that automake allows variable reuse and
rewriting very similar to that supported by make.
When we are linking this monolith, we need to add a
couple of link options, and we do this with a
LDADD primary associated with the
sst_mon prefix. The extra link options we
declare here are added to the eventual link command,
replacing the default set of option
options $(LDADD), so we include that variable
in our version. We also add `fio_link`,
because this monolith needs to be linked against the FIO
library (automake constrains what can appear in the
LDADD variable, and the
`fio_link` is permissable only in Starlink
automake -- see Appendix B for details).
The variables SUBSRC, SUBCSRC
and PRIVATE_INCLUDES are purely user
variables, with no special meaning to automake.
The next bit of magic in this file is
sstsupport_DATA.
In this particular case, we
want to install data files in the same location as the
binaries (why, and whether this is a good thing, is not
for us to worry about here). The obvious thing
would be to say bin_DATA = sun.tex ...,
but automake forbids that particular combination of prefix
and primary, precisely because it wouldn't generally make
sense (see Architecture-independent data files in the
automake manual). Instead, we can take advantage of an
escape-hatch that automake provides: a given prefix, such
as sstsupport, is valid if you also define a
variable of the same name, but with dir
appended. Thus we define sstsupport_DATA and
sstsupportdir, and define the latter to have
the same value as the $(bindir) makefile
variable, as eventually substituted (see section The Uniform Naming
Scheme in the automake manual).
If you look at the real sst component's
Makefile.am file, you will see that it does
in fact use bin_DATA rather than the
sstsupport_DATA illustrated above. This is
because the configure.ac in the
sst component declares the option
STAR_DEFAULTS(per-package-dirs)
(see Appendix A.17) which,
amongst a couple of other magic features, causes the
variable bin_DATA to become legal.
This is a rather special case, and you should not have to
do this sort of semi-licensed hacking very often. In
particular, you do not need to do it in the case of the
Starlink standard directories /star/docs,
/star/etc, /star/examples and
/star/help, since
you can give these directories as prefixes to the
DATA primary. As an example, the HDS
makefile installs a file containing the information it has
determined about the build machine's floating point model,
and this is declared there as follows:
noinst_PROGRAMS = hds_machine
starhelp_DATA = hds_machine.txt
hds_machine_SOURCES = hds_machine.f
hds_machine_LDADD = libhds.la `ems_link` `chr_link` `cnf_link`
hds_machine.txt: hds_machine
./hds_machine >$@
This is enough to build the hds_machine
application at install time, run it, and install the
results in /star/help (with the obvious
changes for prefixes stardocs,
staretc and starexamples).The remaining magic in this file is the
EXTRA_DIST variable.
For all its cleverness,
automake cannot work out that the start.in
source, nor any of the sstsupport_DATA files
are to be distributed, and you need to declare that
explicitly by setting the EXTRA_DIST
variable. Though it is of course deterministic (see
section What Goes
in a Distribution of the manual), I find the
most straightforward way to work out whether anything
needs to go here is to build a distribution and spot what
was missed out.