Getting around make clean or make distclean aclocal failures
Keeping up with source trees for open source projects, it often
happens that you pull the latest source, type make
,
and get an error like this (edited for brevity):
$ make cd . && /bin/sh ./missing --run aclocal-1.14 missing: line 52: aclocal-1.14: command not found WARNING: aclocal-1.14' is missing on your system. You should only need it if you modified acinclude.m4' or configure.ac'. You might want to install the Automake' and Perl' packages. Grab them from any GNU archive site.
What's happening is that make
is set up to run ./autogen.sh
(similar to running ./configure except it does some other stuff tailored
to people who build from the most current source tree) automatically
if anything has changed in the tree. But if the version of aclocal has
changed since the last time you ran autogen.sh or configure, then
running configure with the same arguments won't work.
Often, running a make distclean
, to clean out all local
configuration in your tree and start from scratch, will fix the problem.
A simpler make clean
might even be enough. But when you
try it, you get the same aclocal error.
Whoops! make clean
runs make
, which
triggers the rule that configure has to run before make, which fails.
It would be nice if the make
rules were smart enough to
notice this and not require configure or autogen if the make target
is something simple like clean
or distclean
.
Alas, in most projects, they aren't.
But it turns out that even if you can't run autogen.sh with your
usual arguments -- e.g. ./autogen.sh --prefix=/usr/local/gimp-git
-- running ./autogen.sh
by itself with no extra arguments
will often fix the problem.
This happens to me often enough with the GIMP source tree that I made a shell alias for it:
alias distclean="./autogen.sh && ./configure && make clean"
Saving your configure arguments
Of course, this wipes out any arguments you've previously passed to autogen and configure. So assuming this succeeds, your very next action should be to run autogen again with the arguments you actually want to use, e.g.:
./autogen.sh --prefix=/usr/local/gimp-git
Before you ran the distclean, you could get those arguments by looking at the first few lines of config.log. But after you've run distclean, config.log is gone -- what if you forgot to save the arguments first? Or what if you just forget that you need to re-run autogen.sh again after your distclean?
To guard against that, I wrote a somewhat more complicated shell function to use instead of the simple alias I listed above.
The first trick is to get the arguments you previously passed to configure. You can parse them out of config.log:
$ egrep '^ \$ ./configure' config.log $ ./configure --prefix=/usr/local/gimp-git --enable-foo --disable-bar
Adding a bit of sed to strip off the beginning of the command, you could save the previously used arguments like this:
args=$(egrep '^ \$ ./configure' config.log | sed 's_^ \$ ./configure __')
(There's a better place for getting those arguments, config.status -- but parsing them from there is a bit more complicated, so I'll follow up with a separate article on that, chock-full of zsh goodness.)
So here's the distclean shell function, written for zsh:
distclean() { setopt localoptions errreturn args=$(egrep '^ \$ ./configure' config.log | sed 's_^ \$ ./configure __') echo "Saved args:" $args ./autogen.sh ./configure make clean echo echo "===========================" echo "Running ./autogen.sh $args" sleep 3 ./autogen.sh $args }
The setopt localoptions errreturn
at the beginning is a
zsh-ism that tells the shell to exit if there's an error.
You don't want to forge ahead and run configure and make clean
if your autogen.sh didn't work right.
errreturn does much the same thing as the
&& between the commands in the simpler shell alias above,
but with cleaner syntax.
If you're using bash, you could string all the commands on one line instead,
with && between them, something like this:
./autogen.sh && ./configure && make clean && ./autogen.sh $args
Or perhaps some bash user will tell me of a better way.
[ 13:33 Nov 27, 2015 More programming | permalink to this entry | ]