The canonical target

I’ve already written about the common mistake of using AC_CANONICAL_TARGET in software that is not intended to be used as compiler. Since I’m now using my tinderbox extensively, I’ve thought it might have been a good idea to try checking how many packages actually do call that, that shouldn’t.

The test is really a quick and dirty bashrc snippet:

post_src_unpack() {
    find "${S}" -name configure.ac -o -name configure.in | while read acfile; do
        acdir=$(dirname "$acfile")
        pushd "$acdir"
        autoconf --trace AC_CANONICAL_TARGET 2>/dev/null > "${T}"/flameeyes-canonical-target.log
        if [[ -s "${T}"/flameeyes-canonical-target.log ]]; then
            ewarn "Flameeyes notice: AC_CANONICAL_TARGET used"
            cat "${T}"/flameeyes-canonical-target.log
        fi
        popd
    done
}

This provides me with enough information to inspect the software, and eventually provide patches to correct the mistake. As I said this is a very common mistake, and I’ve fixed quite a few packages for this. Not only it wastes time to identify the target system, but it also provides a totally misleading --target option to the configure script that confuses users and automatic systems alike; if we were to write a software to generate ebuilds out of the source tarball of a software with some basic common options, it would probably be confused a lot by the presence of such an option.

Since the whole build, host and target situation is often confusing, I’d like to try explaining it with some images, I think that might be a good way to show users and developers alike how the three machine definitions interact between each other. Since this is going to be a long post, in term of size, rather than content, because of the images, the extended explanation won’t be present in the feed.

Continue reading on my site for that.

To try explaining this in a very visual way, let’s say we have only three systems, a PowerBook laptop, a standard x86 computer, and a build service using x86-64 servers. The choice of PoweBook as smallest device has been conditioned by the fact it was the only decent image I could find on OpenClipart for a system that would have been easily seen as having a different architecture than the other two. I would have liked an ARM board, but it was wishing too much.

The first obvious case is having a native compiler, no cross-compiling involved at all:

In this case, both gcc’s configure script, the powerpc-linux-gnu-gcc compiler and the hellow program are executed on the same system: the laptop. This is the standard case you have on a Gentoo system when building stuff out of most ebuilds. In this case host, build and target machines are all one the same: powerpc-linux-gnu.

Then there is a very common case for embedded developers, cross-compilers:

In this case gcc’s configure (and thus build) is executed on a PC system, which also will run the powerpc-linux-gnu-gcc compiler, but the hellow program is still executed on the laptop. Host and build machines are i686-pc-linux-gnu while target is powerpc-linux-gnu.

The next scenarios is uncommon for standalone developers but is somewhat with binary distributions for smaller systems:

In this case there is a build service that starts up the build for the compiler, that will then be executed by the laptop directly. In this case the build machine is x86_64-pc-linux-gnu while both host and target are powerpc-linux-gnu.

The final scenario involves all three systems at once and shows exactly the difference between the three machine definitions:

In this case the build service prepares a cross-compiler executed on a PC that will build software to run on the laptop. The build machine is x86_64-pc-linux-gnu, the host machine is i686-pc-linux-gnu and the target is powerpc-linux-gnu.

Now, this works pretty well and sleek for compilers, but what about other software? In most cases you got just two systems involved at most, one that will run the software and one that will build it, so there is no need for a target definition, it’ll all be completed between build and host. And this is why you should not be calling AC_CANONICAL_TARGET unless you can figure out a far-fetched scenario where you can involve three computers with three different architectures, like in the last scenario.

4 thoughts on “The canonical target

  1. I think it’s great that you’re doing all of this! Your work helps all distros, all users, and all developers… and not many people are capable (or interested) in this work, which makes your efforts all that more important. The Free Software community is definitely far better off because of your past, and continuing, work! Thanks again!

    Like

  2. You no doubt already know this but it’s worth pointing out that the latter two cases are called Canadian crosses. Not sure where that name came from though.I seem to recall nano falling foul of that mistake but I tried it several years ago so it may well be fixed now.

    Like

  3. As a user…how does this affect me…what could I expect if the software was done this way?This should be part of /root/.bashrc if using portage?^ mentions nano…should I recompile ‘elvis’ to check fot this? Since that is my editor?

    Like

  4. Nah mostly it’s a developer thing, it really has no impact over users; i have a list of infringing packages, and some I contacted already with patches, but I try to handle those on a case by case, or mostly fix it together with other possible issues.

    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