[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9. Other Derived Objects

Automake can handle derived objects that are not C programs. Sometimes the support for actually building such objects must be explicitly supplied, but Automake will still automatically handle installation and distribution.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.1 Executable Scripts

It is possible to define and install programs that are scripts. Such programs are listed using the SCRIPTS primary name. When the script is distributed in its final, installable form, the `Makefile' usually looks as follows:

 
# Install my_script in $(bindir) and distribute it.
dist_bin_SCRIPTS = my_script

Script are not distributed by default; as we have just seen, those that should be distributed can be specified using a dist_ prefix as with other primaries.

Scripts can be installed in bindir, sbindir, libexecdir, or pkgdatadir.

Scripts that need not be installed can be listed in noinst_SCRIPTS, and among them, those which are needed only by `make check' should go in check_SCRIPTS.

When a script needs to be built, the `Makefile.am' should include the appropriate rules. For instance the automake program itself is a Perl script that is generated from `automake.in'. Here is how this is handled:

 
bin_SCRIPTS = automake
CLEANFILES = $(bin_SCRIPTS)
EXTRA_DIST = automake.in

do_subst = sed -e 's,[@]datadir[@],$(datadir),g' \
            -e 's,[@]PERL[@],$(PERL),g' \
            -e 's,[@]PACKAGE[@],$(PACKAGE),g' \
            -e 's,[@]VERSION[@],$(VERSION),g' \
            …

automake: automake.in Makefile
        $(do_subst) < $(srcdir)/automake.in > automake
        chmod +x automake

Such scripts for which a build rule has been supplied need to be deleted explicitly using CLEANFILES (see section What Gets Cleaned), and their sources have to be distributed, usually with EXTRA_DIST (see section Basics of Distribution).

Another common way to build scripts is to process them from `configure' with AC_CONFIG_FILES. In this situation Automake knows which files should be cleaned and distributed, and what the rebuild rules should look like.

For instance if `configure.ac' contains

 
AC_CONFIG_FILES([src/my_script], [chmod +x src/my_script])

to build `src/my_script' from `src/my_script.in', then a `src/Makefile.am' to install this script in $(bindir) can be as simple as

 
bin_SCRIPTS = my_script
CLEANFILES = $(bin_SCRIPTS)

There is no need for EXTRA_DIST or any build rule: Automake infers them from AC_CONFIG_FILES (see section Configuration requirements). CLEANFILES is still useful, because by default Automake will clean targets of AC_CONFIG_FILES in distclean, not clean.

Although this looks simpler, building scripts this way has one drawback: directory variables such as $(datadir) are not fully expanded and may refer to other directory variables.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.2 Header files

Header files that must be installed are specified by the HEADERS family of variables. Headers can be installed in includedir, oldincludedir, pkgincludedir or any other directory you may have defined (see section The Uniform Naming Scheme). For instance,

 
include_HEADERS = foo.h bar/bar.h

will install the two files as `$(includedir)/foo.h' and `$(includedir)/bar.h'.

The nobase_ prefix is also supported,

 
nobase_include_HEADERS = foo.h bar/bar.h

will install the two files as `$(includedir)/foo.h' and `$(includedir)/bar/bar.h' (see section An Alternative Approach to Subdirectories).

Usually, only header files that accompany installed libraries need to be installed. Headers used by programs or convenience libraries are not installed. The noinst_HEADERS variable can be used for such headers. However when the header actually belongs to a single convenience library or program, we recommend listing it in the program's or library's _SOURCES variable (see section Defining program sources) instead of in noinst_HEADERS. This is clearer for the `Makefile.am' reader. noinst_HEADERS would be the right variable to use in a directory containing only headers and no associated library or program.

All header files must be listed somewhere; in a _SOURCES variable or in a _HEADERS variable. Missing ones will not appear in the distribution.

For header files that are built and must not be distributed, use the nodist_ prefix as in nodist_include_HEADERS or nodist_prog_SOURCES. If these generated headers are needed during the build, you must also ensure they exist before they are used (see section Built Sources).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.3 Architecture-independent data files

Automake supports the installation of miscellaneous data files using the DATA family of variables.

Such data can be installed in the directories datadir, sysconfdir, sharedstatedir, localstatedir, or pkgdatadir.

By default, data files are not included in a distribution. Of course, you can use the dist_ prefix to change this on a per-variable basis.

Here is how Automake declares its auxiliary data files:

 
dist_pkgdata_DATA = clean-kr.am clean.am …

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4 Built Sources

Because Automake's automatic dependency tracking works as a side-effect of compilation (see section Automatic dependency tracking) there is a bootstrap issue: a target should not be compiled before its dependencies are made, but these dependencies are unknown until the target is first compiled.

Ordinarily this is not a problem, because dependencies are distributed sources: they preexist and do not need to be built. Suppose that `foo.c' includes `foo.h'. When it first compiles `foo.o', make only knows that `foo.o' depends on `foo.c'. As a side-effect of this compilation depcomp records the `foo.h' dependency so that following invocations of make will honor it. In these conditions, it's clear there is no problem: either `foo.o' doesn't exist and has to be built (regardless of the dependencies), or accurate dependencies exist and they can be used to decide whether `foo.o' should be rebuilt.

It's a different story if `foo.h' doesn't exist by the first make run. For instance, there might be a rule to build `foo.h'. This time `file.o''s build will fail because the compiler can't find `foo.h'. make failed to trigger the rule to build `foo.h' first by lack of dependency information.

The BUILT_SOURCES variable is a workaround for this problem. A source file listed in BUILT_SOURCES is made on `make all' or `make check' (or even `make install') before other targets are processed. However, such a source file is not compiled unless explicitly requested by mentioning it in some other _SOURCES variable.

So, to conclude our introductory example, we could use `BUILT_SOURCES = foo.h' to ensure `foo.h' gets built before any other target (including `foo.o') during `make all' or `make check'.

BUILT_SOURCES is actually a bit of a misnomer, as any file which must be created early in the build process can be listed in this variable. Moreover, all built sources do not necessarily have to be listed in BUILT_SOURCES. For instance, a generated `.c' file doesn't need to appear in BUILT_SOURCES (unless it is included by another source), because it's a known dependency of the associated object.

It might be important to emphasize that BUILT_SOURCES is honored only by `make all', `make check' and `make install'. This means you cannot build a specific target (e.g., `make foo') in a clean tree if it depends on a built source. However it will succeed if you have run `make all' earlier, because accurate dependencies are already available.

The next section illustrates and discusses the handling of built sources on a toy example.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.4.1 Built Sources Example

Suppose that `foo.c' includes `bindir.h', which is installation-dependent and not distributed: it needs to be built. Here `bindir.h' defines the preprocessor macro bindir to the value of the make variable bindir (inherited from `configure').

We suggest several implementations below. It's not meant to be an exhaustive listing of all ways to handle built sources, but it will give you a few ideas if you encounter this issue.

First Try

This first implementation will illustrate the bootstrap issue mentioned in the previous section (see section Built Sources).

Here is a tentative `Makefile.am'.

 
# This won't work.
bin_PROGRAMS = foo
foo_SOURCES = foo.c
nodist_foo_SOURCES = bindir.h
CLEANFILES = bindir.h
bindir.h: Makefile
        echo '#define bindir "$(bindir)"' >$@

This setup doesn't work, because Automake doesn't know that `foo.c' includes `bindir.h'. Remember, automatic dependency tracking works as a side-effect of compilation, so the dependencies of `foo.o' will be known only after `foo.o' has been compiled (see section Automatic dependency tracking). The symptom is as follows.

 
% make
source='foo.c' object='foo.o' libtool=no \
depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \
depmode=gcc /bin/sh ./depcomp \
gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c
foo.c:2: bindir.h: No such file or directory
make: *** [foo.o] Error 1

In this example `bindir.h' is not distributed nor installed, and it is not even being built on-time. One may wonder if the `nodist_foo_SOURCES = bindir.h' line has any use at all. This line simply states that `bindir.h' is a source of foo, so for instance, it should be inspected while generating tags (see section Interfacing to etags). In other words, it does not help our present problem, and the build would fail identically without it.

Using BUILT_SOURCES

A solution is to require `bindir.h' to be built before anything else. This is what BUILT_SOURCES is meant for (see section Built Sources).

 
bin_PROGRAMS = foo
foo_SOURCES = foo.c
nodist_foo_SOURCES = bindir.h
BUILT_SOURCES = bindir.h
CLEANFILES = bindir.h
bindir.h: Makefile
        echo '#define bindir "$(bindir)"' >$@

See how `bindir.h' gets built first:

 
% make
echo '#define bindir "/usr/local/bin"' >bindir.h
make  all-am
make[1]: Entering directory `/home/adl/tmp'
source='foo.c' object='foo.o' libtool=no \
depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \
depmode=gcc /bin/sh ./depcomp \
gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c
gcc  -g -O2   -o foo  foo.o
make[1]: Leaving directory `/home/adl/tmp'

However, as said earlier, BUILT_SOURCES applies only to the all, check, and install targets. It still fails if you try to run `make foo' explicitly:

 
% make clean
test -z "bindir.h" || rm -f bindir.h
test -z "foo" || rm -f foo
rm -f *.o
% : > .deps/foo.Po # Suppress previously recorded dependencies
% make foo
source='foo.c' object='foo.o' libtool=no \
depfile='.deps/foo.Po' tmpdepfile='.deps/foo.TPo' \
depmode=gcc /bin/sh ./depcomp \
gcc -I. -I. -g -O2 -c `test -f 'foo.c' || echo './'`foo.c
foo.c:2: bindir.h: No such file or directory
make: *** [foo.o] Error 1

Recording Dependencies manually

Usually people are happy enough with BUILT_SOURCES because they never build targets such as `make foo' before `make all', as in the previous example. However if this matters to you, you can avoid BUILT_SOURCES and record such dependencies explicitly in the `Makefile.am'.

 
bin_PROGRAMS = foo
foo_SOURCES = foo.c
nodist_foo_SOURCES = bindir.h
foo.$(OBJEXT): bindir.h
CLEANFILES = bindir.h
bindir.h: Makefile
        echo '#define bindir "$(bindir)"' >$@

You don't have to list all the dependencies of `foo.o' explicitly, only those that might need to be built. If a dependency already exists, it will not hinder the first compilation and will be recorded by the normal dependency tracking code. (Note that after this first compilation the dependency tracking code will also have recorded the dependency between `foo.o' and `bindir.h'; so our explicit dependency is really useful to the first build only.)

Adding explicit dependencies like this can be a bit dangerous if you are not careful enough. This is due to the way Automake tries not to overwrite your rules (it assumes you know better than it). `foo.$(OBJEXT): bindir.h' supersedes any rule Automake may want to output to build `foo.$(OBJEXT)'. It happens to work in this case because Automake doesn't have to output any `foo.$(OBJEXT):' target: it relies on a suffix rule instead (i.e., `.c.$(OBJEXT):'). Always check the generated `Makefile.in' if you do this.

Build `bindir.h' from `configure'

It's possible to define this preprocessor macro from `configure', either in `config.h' (see (autoconf)Defining Directories section `Defining Directories' in The Autoconf Manual), or by processing a `bindir.h.in' file using AC_CONFIG_FILES (see (autoconf)Configuration Actions section `Configuration Actions' in The Autoconf Manual).

At this point it should be clear that building `bindir.h' from `configure' works well for this example. `bindir.h' will exist before you build any target, hence will not cause any dependency issue.

The Makefile can be shrunk as follows. We do not even have to mention `bindir.h'.

 
bin_PROGRAMS = foo
foo_SOURCES = foo.c

However, it's not always possible to build sources from `configure', especially when these sources are generated by a tool that needs to be built first.

Build `bindir.c', not `bindir.h'.

Another attractive idea is to define bindir as a variable or function exported from `bindir.o', and build `bindir.c' instead of `bindir.h'.

 
noinst_PROGRAMS = foo
foo_SOURCES = foo.c bindir.h
nodist_foo_SOURCES = bindir.c
CLEANFILES = bindir.c
bindir.c: Makefile
        echo 'const char bindir[] = "$(bindir)";' >$@

`bindir.h' contains just the variable's declaration and doesn't need to be built, so it won't cause any trouble. `bindir.o' is always dependent on `bindir.c', so `bindir.c' will get built first.

Which is best?

There is no panacea, of course. Each solution has its merits and drawbacks.

You cannot use BUILT_SOURCES if the ability to run `make foo' on a clean tree is important to you.

You won't add explicit dependencies if you are leery of overriding an Automake rule by mistake.

Building files from `./configure' is not always possible, neither is converting `.h' files into `.c' files.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated on July, 20 2009 using texi2html 1.76.