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:
This is enough to build thenoinst_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 >$@
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.