About bootstrapping

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?

3 thoughts on “About bootstrapping

  1. “[…] I’m thinking something along the lines of EINTLTOOLIZE=yes before inheriting the ebuild. […]”You probably meant “before inheriting the _eclass_”, didn’t you? ;-)

    Like

  2. “EINTLTOOLIZE=yes before inheriting the ebuild”I think, it’sn’t neccessary, because the eautoreconf is runs at src_unpack or src_compile and iirc it can use all global variables (eg. WORKDIR, LINGUAS, etc.) so eautoreconf can use it w/o any problem

    Like

  3. As I wrote above, making it automatic on eautoreconf will have problems with deps, by setting EINTLTOOLIZE=yes before the eclass is inherited will make sure that the eclass adds intltool to the build-time dependencies, fixing the problem.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s