Issues with GNU autotools¶
Many source packages use GNU autotools to manage their building. You can typically recognise this because their build instructions tell you to:
./configure; make; make install
and you will typically see files called configure.ac
and Makefile.in
in the source tree.
The GNU autotools derive from a time when writing portable C code was quite difficult, and typically required hand-editing a Makefile (often derived from the X11 build system) in arcane ways. They have, in many ways, been a great success, and for most people, most of the time, are a good thing.
However, their decision to rely only on bash
, m4
and GNU make
renders the system somewhat cumbersome (the original designers did not want to
add yet another tool which would need to be built and/or distributed - in
retrospect a mistake). The lack of adequate documentation, the tendency of
packages to “copy” mostly working autotools setups from other packages, and
the way that changes to autotools propagate do not help (there’s a rant there,
which I shall try to avoid - it’s very boring).
Regardless, when one is assembling a muddle build system, various common problems keep reappearing, and this chapter of the documentation is meant to be a place where we can keep a note of such problems, and their solutions.
Resources¶
There are, at time of writing, two invaluable resources for learning about autotools.
The first is:
Autotools: A practitioner’s guide to GNU AUTOCONF, AUTOMAKE and LIBTOOLJohn CalcoteNo Starch Press, 2010ISBN 1-59327-206-5
This is an introduction to the toolset, with a worked explanation on how to setup a new project (or convert an existing one) to use autotools, written by someone who believes strongly in the system. If you need to use autotools it is worth finding a copy.
The second is online:
His blog, at https://blog.flameeyes.eu/, can also be fairly instructive.
Muddle won’t pull because files have changed¶
Typically, muddle will grumble that:
Failure pulling checkout:SOMENAME/pulled[T] in src/libs/SOMENAME:
There are uncommitted changes/untracked files
M Makefile.in
M aclocal.m4
M configure
M include/Makefile.in
Useful resources for an explanation include:
- http://blog.flameeyes.eu/2008/06/maintaner-mode
- http://www.flameeyes.eu/autotools-mythbuster/automake/maintainer.html
- http://stackoverflow.com/questions/5731023/autotools-force-make-not-to-rebuild-configure-makefile
There are several things going on that cause the problem:
- Various revision control systems (the stackoverflow thread talks about CVS, but this is true of git as well) do not preserve timestamps when creating working files. This means that the relative timestamps of files in a newly clone git directory are not necessarily predictable, and are certainly not guaranteed to be related to the timestamps in the original checkin.
- The main operating system may have a different version of autotools installed (or its constituent packages) than are present/referenced in the checkout SOMENAME.
- There is a thing called “maintainer mode” in the autotools world. This can cause various source files to be regenerated if the autotools system believes this to be necessary. How it works has changed over time, as is often the case with autotools.
- The
configure
script is generated fromconfigure.ac
(which is much more readable!), and theMakefile.in
files are generated fromMakefile.am
templates.
So, it is probable that this source checkout SOMENAME has a configure.ac
which either does not contain the AM_MAINTAINER_MODE
macro (causing it to
default to enabled), or else does contain it but explicitly enables maintainer
mode.
Since maintainer mode is enabled, running ./configure
can trigger a check
to see whether the configure
script is “more recent” than its
configure.ac
, and similarly for other derived files. A check may also be
made against the system autools setup. If the check makes it look as if
something is out of date, then the autotools system can decide to regenerate
files in the source directory, leading to our problem.
There are three possible solutions, of varying complexity.
The Makefile.muddle is building with reference to the source directory - for instance:
config: -mkdir -p $(MUDDLE_OBJ_OBJ) (cd $(MUDDLE_OBJ_OBJ); \ $(MUDDLE_SRC)/configure --host=armv7-none-linux-gnueabi \ --prefix=/ )
and thus the autotools system can overwrite files in that source directory. So a simple, if blunt, solution is to copy the source tree first, and any amendments will then be made in that copy:
config: -mkdir -p $(MUDDLE_OBJ_OBJ) $(MUDDLE) copywithout $(MUDDLE_SRC) $(MUDDLE_OBJ_OBJ) .git (cd $(MUDDLE_OBJ_OBJ); \ ./configure --host=armv7-none-linux-gnueabi \ --prefix=/ )
The snag with this approach is that if a file in the source directory is edited,
muddle reconfigure
is needed to copy the entire source tree over again.However, this is undoubtedly the simplest and quickest solution.
Note
This is a traditional approach, which is known to work, although with the disadvantages mentioned.
If the
configure.ac
file does include theAM_MAINTAINER_MODE
macro, then it should be possible to specify--disable-maintainer-mode
to theconfigure
step:config: -mkdir -p $(MUDDLE_OBJ_OBJ) (cd $(MUDDLE_OBJ_OBJ); \ $(MUDDLE_SRC)/configure --host=armv7-none-linux-gnueabi \ --disable-maintainer-mode \ --prefix=/ )
(Note that the GNU autotools documentation does not mention the limitation that the
AM_MAINTAINER_MODE
macro needs to be present for this to work).Unfortunately, many packages do not include that macro in their
configure.ac
, and there is some debate in the community as to whether it should be there or not (for instance, see http://old.nabble.com/-PATCH-libwacom–Drop-AM_MAINTAINER_MODE-td34561358.html).Warning
This approach should work, but I have not personally had the opportunity to try it, as most of the packages I’ve had to fix were either before I discovered this solution, or have not had
AM_MAINTAINER_MODE
defined.If the
configure.ac
does not contain theAM_MAINTAINER_MODE
macro, it is possible to add it, regenerate the autotools setup for the package, and then commit the lot. TheAM_MAINTAINER_MODE
macro can then either explicitly disable maintainer mode, or enable it and theconfigure
usage can disable it with the--disable-maintainer-mode
switch.As an example of someone external doing this sort of thing, see this pull request on github: https://github.com/craftIk/craftIk/pull/12
To regenerate the
configure
and other files, useautoreconf
- this is silent without-v
switch:cd SOMENAME autoreconf -v
Note that this will typically generate a diretory called
autom4te.cache
, which you should add to your.gitignore
(and perhaps also delete after use).Warning
This is an inadequate summary of what to do, and may be misleading. I hope to improve it in a later version of this document...