automake-1.16: Third-Party Makefiles
22.2 Third-Party ‘Makefile’s
============================
In most projects all ‘Makefile’s are generated by Automake. In some
cases, however, projects need to embed subdirectories with handwritten
‘Makefile’s. For instance, one subdirectory could be a third-party
project with its own build system, not using Automake.
It is possible to list arbitrary directories in ‘SUBDIRS’ or
‘DIST_SUBDIRS’ provided each of these directories has a ‘Makefile’ that
recognizes all the following recursive targets.
When a user runs one of these targets, that target is run recursively
in all subdirectories. This is why it is important that even
third-party ‘Makefile’s support them.
‘all’
Compile the entire package. This is the default target in
Automake-generated ‘Makefile’s, but it does not need to be the
default in third-party ‘Makefile’s.
‘distdir’
Copy files to distribute into ‘$(distdir)’, before a tarball is
constructed. Of course this target is not required if the
‘no-dist’ option (⇒Options) is used.
Hook::) will be passed from the outer package to the subpackage
when the ‘distdir’ target is invoked. These two variables have
been adjusted for the directory that is being recursed into, so
they are ready to use.
‘install’
‘install-data’
‘install-exec’
‘uninstall’
Install or uninstall files (⇒Install).
‘install-dvi’
‘install-html’
‘install-info’
‘install-ps’
‘install-pdf’
Install only some specific documentation format (⇒Texinfo).
‘installdirs’
Create install directories, but do not install any files.
‘check’
‘installcheck’
Check the package (⇒Tests).
‘mostlyclean’
‘clean’
‘distclean’
‘maintainer-clean’
Cleaning rules (⇒Clean).
‘dvi’
‘pdf’
‘ps’
‘info’
‘html’
Build the documentation in various formats (⇒Texinfo).
‘tags’
‘ctags’
Build ‘TAGS’ and ‘CTAGS’ (⇒Tags).
If you have ever used Gettext in a project, this is a good example of
how third-party ‘Makefile’s can be used with Automake. The ‘Makefile’s
that ‘gettextize’ puts in the ‘po/’ and ‘intl/’ directories are
handwritten ‘Makefile’s that implement all of these targets. That way
they can be added to ‘SUBDIRS’ in Automake packages.
Directories that are only listed in ‘DIST_SUBDIRS’ but not in
‘SUBDIRS’ need only the ‘distclean’, ‘maintainer-clean’, and ‘distdir’
rules (⇒Conditional Subdirectories).
Usually, many of these rules are irrelevant to the third-party
subproject, but they are required for the whole package to work. It’s
OK to have a rule that does nothing, so if you are integrating a
third-party project with no documentation or tag support, you could
simply augment its ‘Makefile’ as follows:
EMPTY_AUTOMAKE_TARGETS = dvi pdf ps info html tags ctags
.PHONY: $(EMPTY_AUTOMAKE_TARGETS)
$(EMPTY_AUTOMAKE_TARGETS):
To be clear, there is nothing special about the variable name
‘EMPTY_AUTOMAKE_TARGETS’; the name could be anything.
Another aspect of integrating third-party build systems is whether
they support VPATH builds (⇒VPATH Builds). Obviously if the
subpackage does not support VPATH builds the whole package will not
support VPATH builds. This in turns means that ‘make distcheck’ will
not work, because it relies on VPATH builds. Some people can live
without this (indeed, many Automake users have never heard of ‘make
distcheck’). Other people may prefer to revamp the existing ‘Makefile’s
to support VPATH. Doing so does not necessarily require Automake; only
Autoconf is needed (⇒Build Directories (autoconf)Build
Directories.). The necessary substitutions: ‘@srcdir@’, ‘@top_srcdir@’,
and ‘@top_builddir@’ are defined by ‘configure’ when it processes a
‘Makefile’ (⇒Preset Output Variables (autoconf)Preset Output
Variables.); they are not computed by the Makefile like the
aforementioned ‘$(distdir)’ and ‘$(top_distdir)’ variables.
It is sometimes inconvenient to modify a third-party ‘Makefile’ to
introduce the above required targets. For instance, one may want to
keep the third-party sources untouched to ease upgrades to new versions.
Here are two other ideas. If GNU Make is assumed, one possibility is
to add to that subdirectory a ‘GNUmakefile’ that defines the required
targets and includes the third-party ‘Makefile’. For this to work in
VPATH builds, ‘GNUmakefile’ must lie in the build directory; the easiest
way to do this is to write a ‘GNUmakefile.in’ instead, and have it
processed with ‘AC_CONFIG_FILES’ from the outer package. For example,
if we assume ‘Makefile’ defines all targets except the documentation
targets, and that the real ‘check’ target is named ‘test’, we could
write ‘GNUmakefile’ (or ‘GNUmakefile.in’) like this:
# First, include the real Makefile
include Makefile
# Then, define the other targets needed by Automake Makefiles.
.PHONY: dvi pdf ps info html check
dvi pdf ps info html:
check: test
A similar idea that does not use ‘include’ is to write a proxy
‘Makefile’ that dispatches rules to the real ‘Makefile’, either with
‘$(MAKE) -f Makefile.real $(AM_MAKEFLAGS) target’ (if it’s OK to rename
the original ‘Makefile’) or with ‘cd subdir && $(MAKE) $(AM_MAKEFLAGS)
target’ (if it’s OK to store the subdirectory project one directory
deeper). The good news is that this proxy ‘Makefile’ can be generated
with Automake. All we need are ‘-local’ targets (⇒Extending)
that perform the dispatch. Of course the other Automake features are
available, so you could decide to let Automake perform distribution or
installation. Here is a possible ‘Makefile.am’:
all-local:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) all
check-local:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) test
clean-local:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) clean
# Assuming the package knows how to install itself
install-data-local:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) install-data
install-exec-local:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) install-exec
uninstall-local:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) uninstall
# Distribute files from here.
EXTRA_DIST = subdir/Makefile subdir/program.c ...
Pushing this idea to the extreme, it is also possible to ignore the
subproject build system and build everything from this proxy
‘Makefile.am’. This might sound very sensible if you need VPATH builds
but the subproject does not support them.