Today I sent an email on gentoo-dev to ask developers not to use bootstrap scripts unless absolutely necessary.
Why do I ask this? Well the reason is actually quite simple. We have autotools.eclass and eautoreconf
for very good reasons, using bootstrap scripts means bypassing that code.
First of all, with “bootstrap scripts” I’m referring to all those scripts, usually called autogen.sh
or bootstrap.sh
and variants thereof.
Most of these scripts only call autoconf
, aclocal
, automake
, autoheader
and libtool
. Which is what eautoreconf
does, just it does better. Some scripts do something more, like they call intltoolize
or autopoint
, or do stuff that is totally unrelated to autotools. In those cases you can either ask upstream to split the rest of the stuff in a different script, do the rest of the stuff by hand, or just give up and continue using the bootstrap script (although I very much dislike this last option).
But let’s limit ourselves to the script that are equivalent to eautoreconf
, like the one in libwbxml that I fixed today. The first difference between the eautoreconf
call and the bootstrap script can be seen by users too:
>>> Compiling source in /var/tmp/portage/dev-libs/libwbxml-0.9.0/work/wbxml2-0.9.0 ...
You should add the contents of `/usr/share/aclocal/libtool.m4' to `aclocal.m4'.
configure.in:3: installing `./install-sh'
configure.in:3: installing `./missing'
src/Makefile.am: installing `./depcomp'
src/Makefile.am:6: `CFLAGS' is a user variable, you should not override it;
src/Makefile.am:6: use `AM_CFLAGS' instead.
tools/Makefile.am:6: `CFLAGS' is a user variable, you should not override it;
tools/Makefile.am:6: use `AM_CFLAGS' instead.
./configure --prefix=/usr --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --libdir=/usr/lib64 --build=x86_64-pc-linux-gnu
this, the bootstrap script output, becomes instead:
>>> Unpacking wbxml2-0.9.2.tar.gz to /var/tmp/portage/dev-libs/libwbxml-0.9.2/work
* Applying wbxml2-0.9.2.make_install.patch ... [ ok ]
* Running eautoreconf in '/var/tmp/portage/dev-libs/libwbxml-0.9.2/work/wbxml2-0.9.2' ...
* Running aclocal ... [ ok ]
* Running libtoolize --copy --force --automake ... [ ok ]
* Running aclocal ... [ ok ]
* Running autoconf ... [ ok ]
* Running autoheader ... [ ok ]
* Running automake --add-missing --copy ... [ ok ]
* Running elibtoolize in: wbxml2-0.9.2
* Applying portage-1.5.10.patch ...
* Applying sed-1.5.6.patch ...
>>> Source unpacked.
Nicer to see, to me, tells the user what’s happening, doesn’t show extra warnings that might confuse the user.
Another problem is that usually the bootstrap scripts are either an && concatenation of autotools commands, or don’t check if the previous steps failed, some checks if configure and/or other files got generated, and otherwise tell the user that the call failed. If eautoreconf
fails, it tells the user which step failed, and instruct him to report a bug with the output of the command that failed. Nice.
The scripts are usually used to either add extra directory to search for M4 macro files or to pass options like --foreign
to automake
. In both cases the solution for upstream is to use the ACLOCAL_AMFLAGS
variable in the toplevel Makefile.am that sets the default for automake calls.
For us, well, the latter is no problem at all: --foreign
is used when some of the standard GNU documentation files are missing (because they are not relevant), autotools.eclass checks for those and appends it automatically. The first can be solved by passing the list of directories to append to the search through the AT_M4DIR
variable.
Okay it’s all bell and whistles up to now, but why do I despise bootstrap scripts so much? Well a lot of bootstrap scripts tend to write their own checking code for autoconf and automake versions, as different distributions do it in different ways, and users need not to know the specifics of their distribution usually. The result is that even if you set WANT_AUTOCONF
or WANT_AUTOMAKE
in the ebuild, it might be ignored and the script might be calling a different version of autotools, even a version that is not available for the user.
Also, by using the script you bypass checks for direct autotools calls in the ebuild, which in turn might let you pass unwarned an usage of autotools without proper dependencies (autotools.eclass takes care of that for you). And it doesn’t warn you if you’re running autotools during the src_compile
phase (which is not good, as we want the unpack phase to leave the source ready to be configured and compiled!).
Now of course, as I said some scripts do something more than just re-running autotools, some call autopoint
(gettext) or intltoolize
. These two cases aren’t, for now, handled by eautoreconf
. I think I’ll add some support for those in the next weeks. I’m thinking something along the lines of EINTLTOOLIZE=yes
before inheriting the ebuild.
Making it automatic on eautoreconf
would be nice but it wouldn’t work that well with the automation, as you wouldn’t be getting the dependency added (eautoreconf
runs way after dependency stage).
So at the end of the day the story is: unless you know exactly why you’re doing so, don’t use the bootstrap script! And if you do use it, leave a comment along the lines of # I know, but it's needed
beside its call, so that my grepping through the tree wouldn’t flag it down, deal?