Autotools Mythbuster! You don’t want to canonicalise *that* (and I’m not referring to Ubuntu)

I have to reassure all my readers who actually care about Ubuntu (I mostly don’t): I’m not going to write about Canonical ltd or anything directly related to Ubuntu, or Debian for what matters. This is a blog post that tries to document some very often misused macros in autoconf, hoping to be of general help to developers of free software projects, but not limited to.

For one reason or another a lot of people are quite used to the triplet used for machine definition, stuff like i686-pc-linux-gnu or x86_64-pc-solaris2.11 or powerpc-apple-darwin8.6. Yes the same triplet that is used to define the CHOST value in make.conf in Gentoo. the same triplet you see in GCC, the same triplet that is passed every time at ./configure. This triplet, in autotools, is used in three machine definitions: host, build and target.

All software built with autotools have host and build: the former defines the system where the software will have to run at the end of the build process, the latter states which system is going to be used for building the software. When host and build differ, you’re cross-compiling. Compilers and all the build tools that are specific to a particular machine definition also need a target definition.

Since there are more than one way to define the same machine, autotools have two files, called together gnuconfig, that can reduce the triplets to some common values: config.sub and config.guess. These two files don’t enter in the picture unless you ask for them, though, since they can be superfluous. If your configure never checks the $host and $build variables, since it will identify all that is needed for its build via compile and run tests, it’s pointless to do the reduction, and pointless checks has to be avoided.

So this brings us to the two macros I referred to in the introduction of the blog post: AC_CANONICAL_HOST and AC_CANONICAL_TARGET. These two macros are used to reduce the definitions of host, build and target to their common form that can be more easily tested for. The reason why there are two macros is that the software is, if you think it’s obvious, that not all software needs to have a target. Indeed if you check the output of ./configure --help from a package that expects a target and one that does not, you’ll see that the whole --target support is gone.

In general, if your configure file does not have any test over $host or $build, you should not use AC_CANONICAL_HOST; if your software is not a compiler, and you don’t need to have a “target” system, you don’t need AC_CANONICAL_TARGET. An easy test for the latter would be: does your software have any sense to be called mingw32-software when used under Linux to build for Windows? If not, then you don’t need a target.

It is true that some macros do check the variables, and thus will call those macros themselves; luckily for us, the way autoconf works they’ll be expanded just once, and the problem is solved there: each macro is independent and requires the macros it’ll use.

Unfortunately, not all macros are good; you might remember some time ago SDL enabling AC_CANONICAL_TARGET by default, causing quite a bit of stir since it injected --target support into a huge amount of software that really didn’t need it at all. Similarly, just looking out of my /usr/share/aclocal, I see what I’ d consider a mistake in klibc’s macro file. It requires AC_CANONICAL_HOST and uses $build and $host to test for cross-compiling instead of relying on AC_CHECK_TOOL because it might accept just “klcc”. What is the problem? The problem here is that they assume that klcc might not be the right crosscompiler, and they try to be smarter than autotools.

It’s quite well possible that there is no prefixed name for a cross-compiling tool, because there are toolchains built in such a way that calling cc or ld runs the cross-compiler rather than the host compiler; there is also the option that instead of using the canonicalised host name, the tool is using the host triplet the user passed. And in the whole it runs more check than it should.

Unfortunately libtool still requires AC_CANONICAL_HOST to be tested, but at least you can identify packages that have too extended checks through AC_CANONICAL_TARGET by issuing the command autoconf --trace=AC_CANONICAL_TARGET; it’ll tell ou where in the configure.ac (or configure.in) file the macro is being called, from there you’ll be able to see to get rid of it, hopefully.

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