Building a GCC cross-compiler for MingW

Mon Feb 26 2007

One of the hardest parts in maintaining the Win32 port of PostGIS is that changes to the underlying GEOS library can unintentionally stop it from compiling on Windows. A full compile of GEOS using MingW/MSYS on my reasonably fast Athlon X2 system takes 40 mins, and so makes fixes for the GEOS inlines problem (where the entire compile would complete but the process would fail during link) extremely time-consuming. So I figured that it would be an interesting exercise to see whether I could use a cross-compiler under my installation of Ubuntu to speed up this process.

A quick search on Google for “gcc cross compile” gave back lots of resources to get me started, however some were still lacking in detail as to how to setup the compiler in parallel with an existing GCC compiler. Since there wasn’t much help installing into a specific directory root, I now reproduce below the steps required to setup a GCC/MingW cross compiler:

  1. Download binutils to $HOME/mingw-build (latest version was 2.17).

  2. Build the binutils package:

    ./configure --prefix=$HOME/mingw-build/rel --target=i686-pc-mingw32
    make
    make install
    

    Note that I had to do “make” followed by “make install” since running “make install” directly didn’t work for me.

  3. Download the latest MingW runtime and API files from the MingW project. At the time of writing these were w32api-3.6.tar.gz and mingw-runtime-3.9.tar.gz. Extract these in the directory $HOME/mingw-build/rel/i686-pc-mingw32 which was created in step 2.

  4. Download and install GCC 3.4.2 (this is the version currently supported by the MingW project)

    PATH=$HOME/mingw-build/rel/bin:$PATH \
    ./configure --prefix=$HOME/mingw-build/rel --target=i686-pc-mingw32
    make
    make install
    

And that was it. So now that the cross-compiler was setup, time to test the new setup on GEOS to see if it would compile any faster. The version of GEOS tested was GEOS 3.0.0rc4. Running ./configure for GEOS didn’t work the first time, since autotools refuses to detect 64-bit integer types in a cross-compile environment since the capabilities of the target and the host systems can be different. I eventually got GEOS to work with the following ./configure statement:

   PATH=$HOME/mingw-build/rel/bin:$PATH CXXFLAGS="-g -O2 -DHAVE_INT64_T_64" \
   ./configure --host=i686-pc-mingw32 --target=i686-pc-mingw32 --prefix=$HOME/tmp/geos/rel

I then invoked “make” using the following:

   PATH=$HOME/mingw-build/rel/bin:$PATH make

So how long did it take to build the cross-compiled DLL on Ubuntu instead of using MSYS on Windows? 7 mins! During testing, I did find that the resulting DLL still had the issue where C++ exceptions are not correctly propogated back up to the C code in PostgreSQL. It appears that this is because the linker option “-lstdc++” doesn’t quite work correctly in the cross-compile environment, so if anyone can shed light on this that would be great. However, I now have the ability to check the latest GEOS builds don’t break the MingW compiler process without having to wait 40 mins each time - and that is a good thing.