Compiling x86-linux under win32

My exploration of cross-compiling must include cygwin: the linux-like API for Windows. I will be building a gcc toolchain using cygwin on Windows XP SP2 (win32, naturally) to join my distcc network of compilers. Most of this is gathered from the gentoo-wiki, however some of the steps were outdated and required some ingenuity.

1. Environment Variables & Sources

cygwin$ export PREFIX=/usr/local/cross-linux
cygwin$ export SRC_ROOT=~/
cygwin$ export BUILD=i686-pc-cygwin
cygwin$ export HOST=i686-pc-cygwin
cygwin$ export TARGET=i686-pc-linux-gnu
cygwin$ export BUILDDIR=$SRC_ROOT/build
cygwin$ export PATH=$PATH:$PREFIX/bin

Once the environment is set up, get all the sources you will need onto your cygwin box. You’ll need binutils, glibc, glibc-linuxthreads, distcc and gcc. The easiest place is straight from the distfiles on your gentoo/linux box; place them in $SRC_ROOT.

2. Build binutils

cygwin$ cd $SRC_ROOT
cygwin$ tar -xjvf binutils-2.15.92.0.2.tar.bz2
cygwin$ mkdir $BUILDDIR/binutils
cygwin$ cd $BUILDDIR/binutils
cygwin$  ../../binutils-2.15.92.0.2/configure --with-included-gettext --target=$TARGET --host=$HOST --build=$BUILD --prefix=$PREFIX -v && make && make install

Test to see that everything is in order. (If you get ‘command not found’ then you haven’t set the $PATH properly)

cygwin$ $TARGET-ld --version
GNU ld version 2.15.92.0.2 20040927
Copyright 2002 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License.  This program has absolutely no warranty.

3. Build glibc under linux
Since glibc is the most time-consuming compile, it is easiest to build it on your gentoo/linux box and then ship it over to cygwin.

linux$ cd /tmp
linux$ mkdir glibc && cd glibc
linux$ tar -xjf /usr/portage/distfiles/glibc-2.3.5.tar.bz2
linux$ cd glibc-2.3.5
linux$ tar -xjf /usr/portage/distfiles/glibc-linuxthreads-2.3.5.tar.bz2
linux$ mkdir ../build && cd ../build
linux$ ../glibc-2.3.5/configure --enable-add-ons --prefix=/usr/local/cross-linux/i686-pc-linux-gnu && make && make install

This will take some time, amuse yourself with the thought that soon you’ll be compiling faster than any of your friends have ever imagined! (or not)
So now you have glibc built and ready to go on your cygwin.

cygwin$ cd /
cygwin$ ssh gentoobox '( cd / ; tar -cf - usr/local/cross-linux )' | tar -xf -
4. Build gcc
Remove the .exe suffix if you wish, as stated on the wiki:
On Cygwin, GCC automatically adds the “.exe” extension, in following with the Windows file extension convention. Because you are cross-compiling for Linux, you may wish to modify GCC not to do this. To do so, open $SRC_ROOT/gcc-3.3.6/gcc/config/i386/xm-cygwin.h and comment out the EXECUTABLE_SUFFIX macro. This step is not strictly necessary for distcc use, but there isn’t any obvious reason why programs compiled for Linux should need this extension.
Then, if all goes well up to this point you can build gcc.
cygwin$ cd $BUILDDIR
cygwin$ mkdir gcc && cd gcc
cygwin$ ../../gcc-3.3.6/configure --enable-languages=c,c++ --with-included-gettext --enable-shared --enable-threads=posix --with-headers=$PREFIX/i686-pc-linux-gnu/include --target=$TARGET --host=$HOST --build=$BUILD --prefix=$PREFIX -v && make && make install

A little ways through the configuration you’ll happily notice:

Links are now set up to build a cross-compiler for i686-pc-linux-gnu from i686-pc-cygwin.

Don’t get your hopes up yet, not until gcc is done making at least.

Common problems with the headers:
The only error I noticed during gcc make was that it had trouble finding some of the linux headers it needed. Firstly make sure you got all the files from the include directory off your linux host and then look into the error to see what other headers are missing. In my case I had to specifically copy the asm-generic folder over from /usr/include (on my linux host). Copy whatever headers are necessary and re-make.

5. Build distcc and start daemon
This should be the easiest, and yet most important part of this installation.

cygwin$ tar -xvf distcc-2.18.3.tar.bz2
cygwin$ cd distcc-2.18.3
cygwin$ ./configure --prefix=/usr/local make && make install
cygwin$ export PATH="/usr/local/cross-linux/bin:/usr/local/cross-linux/$target/bin:$PATH"
cygwin$ distccd --daemon --nice 19

Now the daemon is up and running you can add this host to your distcc pool and test if it distributes jobs. For additional information (such as how to integrate distcc with windows services) check out the wiki page.

Leave a Comment