On Wednesday 26 March 2008 01:56, Chris Sutcliffe wrote:
> > These more recent references show how I built binutils, for the
> > purpose of regenerating the source tarball in fully `distributable'
> > condition: http://article.gmane.org/gmane.comp.gnu.mingw.devel/2678
> > http://article.gmane.org/gmane.comp.gnu.mingw.user/25029
> I've followed Keith's examples and generated a new binutils
> distribution with the following options:
> $ ../binutils-2.18.50/configure --prefix=/mingw/ --build=mingw32
> --host=mingw32 --target=mingw32 --with-gcc --with-gnu-as
> --with-gnu-ld --disable-nls
> $ make CFLAGS="-s -O2 -mms-bitfields -mtune=i686"
> $ make prefix=`cd ../dist;pwd` install
Hmm. Seeing that all spelt out just reinforces the impression of how
anomalous build = host = target = mingw32 is. Logically, one one think
that, since this is a self hosted build, none of them should be needed.
Unfortunately, if they are omitted, the build process guesses the target
type as `i?86-pc-mingw32', and generates a tool chain structure which
is incompatible with the way Danny built all our past GCC releases.
When I originally worked through this exercise, I used my cross hosted
i586-mingw32 tool chain, configured with `--build=i686-pc-linux' and
`--host=i586-mingw32'. I didn't specify --target, since I was building
a tool chain which would run on an i586-mingw32 host, targetting a
similar host; thus, logically the tools would be self hosted, and any
specification of --target would be redundant. This resulted in a full
build of the tool chain, but naturally, I ended up with a directory
name of i586-mingw32 where a standard MinGW build would have mingw32.
I next tried simply adding a `--target=mingw32' to my original configure
command, leaving it otherwise unchanged. This did have the effect, as
expected, of building the tool chain with those components needed to
support the compiler correctly placed in a `mingw32' directory, but now
the public versions of the tools, and their associated man pages were
all qualified by the addition of a `mingw32-' prefix on the file names.
Thinking about it, that makes sense, for I've now configured it as a
canadian cross, to run on an i586-mingw32 host, but to generate code
for a *different* type of host, namely `mingw32'; thus the tool chain
is named, to appropriately identify that target.
Additionally, having built the binutils using this canadian cross
method, I observed that only one of the expected libraries was built,
(libiberty.a), and others that I expected were missing. I don't know
why that is, and I don't have the energy to investigate further; the
messages generated during the `make install' did include warnings about
*.la modules not being installed, and their associated *.a modules were
also missing, so I guess it's a libtool issue, but as I've never used
libtool, I don't consider myself qualified to comment.
The lesson here is, that to build the crossed native tool chain to both
run on *and* target a `mingw32' host, we need a cross compiler which
itself *directly* targets `mingw32', from the build machine. Thus, I
built a new linux-x-mingw32 cross compiler, invoked for --host=mingw32
rather than --host=i586-mingw32. Sure enough, when I use that with
just `--build=i686-pc-linux --host=mingw32', and omitting the --target
spec altogether, I can successfully reproduce the structure of Chris'
build, as I would expect.
Not satisfied with this, I decided to build it again, but self hosted on
the Win2K box at work -- and what a painful exercise that turned out to
be. A job which completes in five or six minutes on my Ubuntu-6.06-LTS
box took a full hour, on the similarly specced Win2K box, only to have
it blow up at the end, because binutils-2.18.50/ld/deffilep.[ch] are
missing from the binutils-2.18.50-20080109-src.tar.gz I downloaded from
our SF site this morning. (I thought this had been fixed, but it was
apparently overlooked; I've taken the liberty of adding an updated
source tarball to Chris' latest SF release).
Anyway, having eventually completed this exercise, I can confirm that
neither the --host nor the --target spec is absolutely necessary in the
above command, (although it does no harm to specify them in *addition*
to --build); the --build spec alone is necessary and sufficient. Why
should it be --build and not --host or --target? Well, the configure
paradigm begins by identifying the build type; if it isn't explicitly
defined by a --build spec, it is guessed, and set to the full canonical
triplet, (`uname -m`-pc-mingw32, for the mingw32 build case, where we
want it to simply be mingw32). Next, the runtime host is identified;
if this isn't explicitly set with --host, it defaults to the same as
the build spec, either as set by --build, or as guessed. Technically,
it is incorrect to specify --host without --build; if the explicitly
specified --host differs from the guessed --build, configure will set
up the build for cross compilation, which isn't what we want for a self
hosted build. Finally, configure identifies the target spec; again, if
this isn't explicitly set, by a --target option, then it defaults to
the setting established for --host, either as specified explicitly, or
as itself inherited from --build. At this point, if the target spec
differs from the host spec, then configure sets up the build to create
a set of tools for deployment as a cross tool chain.
You are welcome to try this for yourselves, (it takes forever to try
each of the three cases on a Win32 box, if your's is as slow as mine);
I already knew what to expect, but experimental proof is always better
than assumed knowledge. To summarise:
- Specifying only --build=mingw32 will DTRT;
- Specifying only --host=mingw32 may *accidentally* DTRT, (I
declined to try this one), but is technically incorrect;
- Specifying only --target=mingw32 does *not* DTRT.
The bottom line of all this is, for a self hosted build of binutils for
public distribution, the *minimum* acceptable command sequence is:
$ path/to/binutils-src configure --prefix=C:/mingw --build=mingw32 \
--with-gcc --with-gnu-as --with-gnu-ld --disable-nls
$ make CFLAGS='-s -O2 -mms-bitfields -mtune=i686'
$ make prefix=/path/to/dist/image install
$ ( cd /path/to/dist/image ; tar cf - ) | gzip -c > $BIN_TARFILE
with `/path/to/dist/image' referring to a location on a FAT file system;
(to ensure that the installed image has no hard links).
Alternatively, for anyone wishing to build such packages on a cross host
platform, the cross compiler *must* be configured for a target which is
identically equal to `mingw32', (*not* i386-pc-mingw32, nor any of the
other variants we often see). With this proviso, the build commands
are identically the same, *except* that:
`--build=mingw32' is replaced by `--build=build-id --host=mingw32'
`--with-sysroot=/whatever' may be required.
 This is also necessary, for cross hosted builds.
 With this in mind, we should probably modify our cross compiler
build scripts, to make the default target identifier identically equal
to `mingw32', instead of the current `i386-mingw32' default.