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