Is "host" the build or the target system?

Magnus Ihse Bursie magnus.ihse.bursie at oracle.com
Thu May 24 13:21:25 PDT 2012


On 2012-05-24 17:48, Kelly O'Hair wrote:
> Ok now I'm completely confused...
That's the typical reaction when confronting autoconf cross-compilation. ;-)

There's a lot of bad or incorrect advice floating around on the net, 
which doesn't help the situation. Neither does the fact that autoconf 
itself has changed during the year, so the default way of specifying 
cross-compilation has been deprecated, and then the new way has been 
deprecated and so on. You might still find old instructions on the net 
such as "configure mips-dec-ultrix4.2" or "CC=m68k-coff-gcc configure".

The key to understanding the autoconf terminology is to understand that 
it was designed to cross-compile cross-compilers! Yes. Read that again. 
Cross-compile cross-compilers. This adds an extra level of complexity, 
and is a great source for confusion since it's easy to miss if you're 
talking about the first or the second cross-compilation in that scheme.

A cross-compiler is a tool that by it's nature has two platforms 
associated with it: the one it can run on (A), and the one it produces 
code for (B).

So if you just would build a cross-compiler locally, you might be 
tempted to call A "host" and B "target", because that's extremely 
suitable terminology from the resulting binary's point of view.

However, if you want to *cross-compile* this cross-compiler, you need to 
introduce a third platform, the one on which you perform the build (C). 
So then you call this "build", since there is where you build it. And 
now you have:

"build" -- the platform on which you build the binary
"host" -- the platform on which the resulting binary will run
"target" -- the platform for which the resulting compiler will generate 
code for

And then you take your autoconf system and start building other stuff 
than cross-compilers, and then instead of redesigning, you say "host is 
your target platform" and "target is not used unless you're building a 
cross-compiler".

The fact that it's taken me more than one page to explain this says 
something about how broken it is. :-) As is the fact that the pages you 
found are incorrect or confusing. One gives the broken (but 
sane-looking) example of "CC=m68k-coff-gcc configure 
--target=m68k-coff". The other one is talking about cross-compiling 
cross-compilers, but are then talking about the resulting binary and how 
that will cross-compile, and not about the primary cross-compilation 
process itself, which makes it misleading.

To add to the mess, you must always specify --build when you specify 
--host when you want to cross-compile, even though autoconf can properly 
(in most realistic scenarios) detect your build platform due to 
"historical reasons" (see 
http://www.gnu.org/software/autoconf/manual/autoconf.html#Specifying-Target-Triplets 
for an authorative source). If you don't, autoconf behaves slightly 
incorrect which might, or might not, cause strange problems later on...

If you specify --host but not --target, autoconf will automatically set 
--target to the same as --host. Older versions of autoconf also set 
--build to --host automatically if --host was specified bit --build was 
not, but this is not the case for the version we are using.

Autoconf changes it behavior if you specify a different --host, but it's 
more agnostic to your --target. In fact, if you're not building a 
cross-compiler, you can set --target to just about anything. From 
autoconf's view, it would be meaningless to explicitely set target if 
you are not build a cross-compiler. This fact is what I used in my fix.

So what I did to clear up this mess was to create a wrapper that did:
a) If --host and/or --target was set, but not --build, then explicitely 
set --build to the auto-detected platform, to make autoconf behave properly.
b) If --target was set, but not --host, then explictely set --host to 
the same as target. (Autoconf itself does the other way round, as I said).

The effect of this is:
* You can run "configure --target=foo". This will, on the inside, be 
rewritten to: "configure --target=foo --host=foo --build=<your 
automatically detected platform>". Which is what you wanted. And this is 
the format I would suggest we publish in the documentation.
* ... but you can also run "configure --host=foo", and this will be 
rewritten as "configure --host=foo --build=<your automatically detected 
platform>", which is most likely what you wanted if you were partly 
knowledgeable about configure syntax, but not completely.
* ... but you can also run "configure --build=override_my_platform 
--host=foo --target=this_makes_no_sense" and get the same result as 
without my wrapper, i.e. you can still get the exact same behavior as 
normal configure if you just name all arguments explicitely. (Not that I 
believe this scenario makes much of a sense, though.)

I thought this was a quite good solution for this messed-up problem. :-)

/Magnus




More information about the build-infra-dev mailing list