-m64, to produce either 32 or 64 bit Windows binaries), as well as static and shared library generation on a Linux host platform, using the current latest official versions of everything. Most of what I'm going to describe is based on the mingw-w64-howto-build guides that one can find here, with fixes added. This guide is intended to be fairly generic, so that you can use it as a base for more specific settings.
First of all, a bit of a warning. If you have anything urgent coming up, if your boss wants something else done by tomorrow or if you have a wife & kids requiring your attention, do not start building a cross compiler manually! You should only ever do so if you can totally waste a couple of days trying to figure out how to fix that £$%^& non working cross compilation process. As you will see soon enough, gcc is a pretty wild beast when it comes to cross compilation, and no matter what you do or which guide you follow, you're pretty much guaranteed that it's going to be anything but a smooth ride. If you don't have time to waste, there are scripts here and there that should take care of taming the beast for you. Of course, these scripts won't usually let you pick up the very latest versions, as we are going to do here, but you can't have it all. Also, of course, I make no guarantee whatsoever that what I'm describing below will actually work for you. You have been warned!
Downloads & Prerequisites
As you should know, there's a bit more to compiling MinGW than just picking up the latest MinGW and gcc. You also need binutils and gcc also relies on a few libraries, so below is the list of everything you'll need, with the latest versions available at the time of this post (2010.07.10):
- MinGW-w64 (latest from svn)
- binutils 2.20.1
- gcc 4.5.0
- gmp library 4.3.2
- mpfr library 3.0.0
- mpc library 0.8.2
You will also need some disk space (preferably on a fast "disk" device) in the range of 2 to 3 GB for the whole compilation process. Better create a working directory and download everything here. Everything apart from MinGW itself can be gotten using wget or your preferred method of download, so you should go ahead and pick a copy of everything from the list above. For MinGW, just fire up the following to retrieve the source:
svn co https://mingw-w64.svn.sourceforge.net/svnroot/mingw-w64 mingw-w64Another prerequisite that you shouldn't overlook is, since the compilation process is fraught with disappointments and restarts, the fastest and the more cores your CPU is/has, the better. Better try that process on the fastest Linux machine you can get your hands on first, and once you're satisfied that your compilation should work, do it on a slower machine if that's your final target.
For the record, I used a quad core Slackware 13.0 64 bit Linux server, which I'm hoping should be generic enough to have this guide apply to other Linux flavours.
File extraction and directory settings
If you haven't done so by now, you should extract all the tar archives downloaded above into your working directory. Now, a lot of guides will have you go through gmp+mpfr+mpc installation before you can fiddle with gcc, but that's really pointless. The newer gcc sources are designed to pick up and compile gmp, mpfr and mpc if they are available in the gcc source directory. Moreover, I have had trouble getting gcc 4.5.0 recognize the very new mpfr 3.0.0 when compiled as standalone, whereas it doesn't seem to have a problem picking it up from its source directory.
Therefore, here's what you should do once you have extracted everything:
mv mpfr-3.0.0/ gcc-4.5.0/mpfr mv gmp-4.3.2/ gcc-4.5.0/gmp mv mpc-0.8.2/ gcc-4.5.0/mpcOnce this is done, this is the content you should have in your working directory:
binutils-2.20.1/ binutils-2.20.1.tar.bz2 gcc-4.5.0/ gcc-4.5.0.tar.bz2 gmp-5.0.1.tar.bz2 mingw-w64/ mpc-0.8.2.tar.gz mpfr-3.0.0.tar.bz2
For most of the configuration, we will use the defaults, therefore, the binaries and includes will use
/usr/localas their base (specific MinGW-w64 subdirectories will be created, don't worry). The only option I'm going to consistently add when running the versions configure is the
--disable-nlsto try to speed up things a little bit by disabling non Western language support.
Also, you should never compile any part of a cross compiler from within the extracted source directory. If you do, the whole process is bound to fail. Instead, we will create external build directories (eg.
binutils-build) in our working space for each source we need to go through.
Also, since I am lucky enough to run on a quad core, I'm going to use the parallel processing option of
-j) to considerably speed up the whole compilation process. The rule of thumb is to use
j#with # being the number of cores you have at your disposal (altough I've also seen people doubling that number). Hence, almost every
makecommand we call below will be affixed with
Oh yeah, and some people will advise to add a
--build=<build-machine-triplet>all over the place, but most of the scripts we use are smart enough to detect cross compilation, so this is not necessary. You might see some warnings about
--buildnot being specified, but you shouldn't worry too much about them.
Finally, gcc compilation is a bit unpredictable, especially if you use
-jon make (but even without, weird things happen), so if your make process generates an error for any reason, the first thing to try is make again, to see if things get further. Even without
-j, it sometimes takes 2 or 3 passes to get a specific section of the compilation working.
And now the fun begins. Didn't encounter much of any issues with binutils, so the process goes as follows:
mkdir binutils-build; cd binutils-build ../binutils-2.20.1/configure --disable-nls --target=x86_64-w64-mingw32 --enable-targets=x86_64-w64-mingw32,i686-w64-mingw32 make -j4 make installIn the above, the
--target indicatesthat we ultimately want to produce a MinGW compiler that can produce x86_64 binaries (i.e. MinGW-w64), and the
--enable-targetswith 2 parameters is for multilib support, with 64 (x86_64) and 32 (i686) bit.The end result of all this is that you should get a bunch of
/usr/local/bin(ar, ld, etc)
Pay attention here: This is the headers install => the configure we run is NOT the one from
trunk/but the one from
trunk/mingw-w64-headers/. If you try to run the configure from
trunk/at this stage, of course it will fail.
cd ..; mkdir mingw-build; cd mingw-build ../mingw-w64/trunk/mingw-w64-headers/configure --host=x86_64-w64-mingw32 make installThis should copy the MinGW headers into
MinGW directories and symlinks
With the above steps, you should end up with a
/usr/local/x86_64-w64-mingw32/directory that also contains a
lib/directory (which will be used for the 64 bit version of the libraries). If that's not the case you should create it. Now, for multilib, we'll also need a
lib32/directory, and some parts of MinGW expect a few specific directories, like
/usr/local/mingw, so we create all that:
ln -s /usr/local/x86_64-w64-mingw32 /usr/local/mingw mkdir -p /usr/local/x86_64-w64-mingw32/lib32 ln -s /usr/local/x86_64-w64-mingw32/lib /usr/local/x86_64-w64-mingw32/lib64
Gcc, pass 1
Now things start to get real (and problems start to appear if you don't use the right configure options):
cd ..; mkdir gcc-build; cd gcc-build ../gcc-4.5.0/configure --disable-nls --target=x86_64-w64-mingw32 --enable-languages=c,c++ --with-system-zlib --enable-multilib --enable-version-specific-runtime-libs --enable-shared --enable-fully-dynamic-stringOK, a little clarification about our configure options:
--enable-languages=c,c++, because, who the hell compiles 64 bit Windows binaries in Fortran or Ada, and your time is precious (plus, I think the Fortran/Ada source generate some errors). C and C++ are all you need.
--with-system-zlib, at least on Slackware, you do want to use that option to avoid an uncorrectable "
Link tests are not allowed after GCC_NO_EXECUTABLES" error in the
zlib/directory provided by gcc. And I'm at loss to figure out why gcc does include the sources for zlib in their archive, but not the ones for gmp, mpc, mpfr, as it'd make life a lot easier for everybody.
--enable-fully-dynamic-string, because some people use these and say they are useful.
[UPDATE: 2010.09.09] According to the MinGW-w64 developers, you should NOT use
--enable-version-specific-runtime-libs, as this causes issues. There is currently a long discussion on the MinGW-w64 mailing list about this. Make sure you read it! I may update this guide at some stage
--enable-multilib, to have
--enable-shared, to be able to compile DLLs as well as static libraries.
make all-gcc -j4Yay, our first compilation error (sadly, won't be the last!). The above fails on
checking for gmp internal files... configure: error: header files gmp-impl.h and longlong.h not found make: *** [configure-mpfr] Error 1To fix that error:
cp ../gcc-4.5.0/gmp/gmp-impl.h gmp; cp ../gcc-4.5.0/gmp/longlong.h gmpAfter that, the process should complete successfully with:
make all-gcc -j4 make install-gccNote that if you get other errors during the build (eg. "
Link tests are not allowed after GCC_NO_EXECUTABLES"), just try without
-ja couple of times to see if this is really a permanent error, or just gcc screwing with your nerves.
Nothing fancy here. If you use the latest from svn, things should compile pretty nicely with:
cd ../mingw-build ../mingw-w64/trunk/configure --disable-nls --host=x86_64-w64-mingw32 --enable-lib32 make -j4 make install -j4I think
--enable-lib32is superfluous, as recent MinGW-w64 seem to be hardwired for multilib by default. Just make sure that 32 and 64 bit are enabled on the configure summary screen.
Gcc, pass 2
"It's right when you start seeing the light at the end of the tunnel, that the arch collapses."
Thought you were out of the woods? Think again:
cd ../gcc-build make -j4will choke on:
/usr/local/x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/local/x86_64-w64-mingw32/lib/libmingw32.a when searching for -lmingw32and a whole bunch of similar errors. Obviously, since we're in
gcc-build/x86_64-w64-mingw32/32/libgcc/when that happens,
ldshould be looking in
Now, there's probably a smarter approach, but the easiest way I found to fix this is to:
- copy the
CCline into a
CC32line and replace all the
GCC_FOR_TARGET = $(CC)with
GCC_FOR_TARGET = $(CC32)
CCline doesn't work (which I guess is due to libtool use)! You need to create a new
make -j4You might get a "
Link tests are not allowed after GCC_NO_EXECUTABLES" (what the heck does that error actually mean anyway?). If that happens, just retry... until it breaks again with the "
skipping incompatible when searching for -lmingw32" error again in
Same trick as above applies, with editing the
Makefile, only this time you can edit the
CPPvariables directly and just replace
make -j4Yup, choked again, this time in
/bin/sh: ../libtool: No such file or directoryEasiest solution I found:
cp ./x86_64-w64-mingw32/libssp/libtool ./x86_64-w64-mingw32/libstdc++-v3Then once more:
make -j4Might get a few errors, that go away on retry, and then:
../../../../gcc-4.5.0/libstdc++-v3/src/atomic.cc:26:21: fatal error: gstdint.h: No such file or directoryEasy to fix:
ln -s /usr/local/mingw/include/stdint.h /usr/local/mingw/include/gstdint.h make -j4...and then again:
make: Entering directory `/mnt/hd/src/clean/gcc-build/x86_64-w64-mingw32/32/libstdc++-v3' make: *** No rule to make target `all'. Stop.Well, no surprise: there's no makefile in
<your_working_dir>/gcc-build/x86_64-w64-mingw32/32/libstdc++-v3/! How I fixed it?
rm -r x86_64-w64-mingw32/32/libstdc++-v3 ln -s x86_64-w64-mingw32/libstdc++-v3/32 x86_64-w64-mingw32/32/libstdc++-v3 make -j4...and once more, plenty of errors in
lib32. At least we can't say gcc compilation isn't keeping us entertained. This time, we can edit
./x86_64-w64-mingw32/32/libssp/libtooland do a search for
-m32. For each line that has
-m32, just replace
$ make -j4YAY!!! Completion at last! Just one final thing to do:
make install -j4If you managed to make it through that last ordeal, you should now have a fully working MinGW-w64 gcc compiler, capable of producing 32 and 64 bit windows binaries, as well as static or dynamic (DLL) libraries, and using nothing but the latest versions of all the tools. Pretty cool huh?
To compile, just remember to add a
--host=x86_64-w64-mingw32when running configure, and possibly export a
CFLAGS=-m32if you want to produce 32 bit binaries.