|  | The Advance Guide to | 
|  | Building the Mingw-w64 x86_64-w64-mingw32 cross-compiler | 
|  |  | 
|  | == About this document == | 
|  |  | 
|  | This document describes more advanced methods in building the mingw-w64 | 
|  | cross compiler. It also includes details about the toolchain | 
|  | dependencies and relevant options that can be passed to the GCC | 
|  | configure. | 
|  |  | 
|  | The commands are run under a MSYS/MinGW setup unless specified otherwise. | 
|  | Using Cygwin or any other POSIX compatible shell should work. | 
|  |  | 
|  | == Targeted audience == | 
|  |  | 
|  | This document assumes readers are familiar with the UNIX Command Line | 
|  | and building the GNU toolchain in general, but would want a more fine | 
|  | grained control over the capabilities of the cross compiler. | 
|  |  | 
|  | For a basic guide on building the mingw-w64 toolchain, please refer to | 
|  | "mingw-w64-howto-build.txt". | 
|  |  | 
|  | == Notes about LTO == | 
|  |  | 
|  | LTO for COFF targets can be enabled without installing libelf, as of gcc-4.6.0. | 
|  |  | 
|  | == Version changes == | 
|  |  | 
|  | Date /        Version /    Author | 
|  | 2009-10-09    1.0          Jonathan Yong <jon_y[a]users.sourceforge.com> | 
|  | 2010-01-03    1.1          Jonathan Yong <jon_y[a]users.sourceforge.com> | 
|  | 2010-05-18    1.11         Jonathan Yong <jon_y[a]users.sourceforge.com> | 
|  | 2010-08-31    1.12         Jonathan Yong <jon_y[a]users.sourceforge.com> | 
|  | 2013-01-27    1.13         Jonathan Yong <jon_y[a]users.sourceforge.com> | 
|  |  | 
|  | == Table of Contents == | 
|  |  | 
|  | * Some Basic Info about mingw-w64                         [SBSCINF] | 
|  | * Host Support Libraries                                  [HOSTLIB] | 
|  | * The GNU MP Bignum Library                           [BGMPLIB] | 
|  | * MPFR                                                [BMPFRLB] | 
|  | * Multiprecision                                      [BMPCLIB] | 
|  | * The Parma Polyhedra Library                         [BPPLLIB] | 
|  | * The Clunky Loop Generator (PPL port)                [BCLGLIB] | 
|  | * Target Support Libraries                                [TGTSPLB] | 
|  | * pthreads-win32                                      [PTHRW32] | 
|  | * Building the Multilib Cross MinGW-w64 GCC the | 
|  | lazy way(With ADA support and libgomp)                [LAZYW64] | 
|  | * ADA Bootstrap Phase                                 [ADABOOT] | 
|  | * MinGW-w64 cross Binutils                            [CRSBINU] | 
|  | * Install mingw-w64 Headers                           [MGW64HD] | 
|  | * Setup Symlinks                                      [SETSYML] | 
|  | * Build Core GCC                                      [BCORGCC] | 
|  | * Build the mingw-w64 CRT                             [BMGWCRT] | 
|  | * Build libgcc                                        [BLIBGCC] | 
|  | * Build pthreads                                      [BPTHR32] | 
|  | * Continue the build                                  [CTNTBLD] | 
|  |  | 
|  | You can search the keys (i.e. [BMPCLIB]) to jump to that section. | 
|  |  | 
|  | == Some Basic Info about MinGW-w64 == [SBSCINF] | 
|  |  | 
|  | MinGW-w64 began as a fork of mingw.org MinGW to support 64bit windows as | 
|  | a target. | 
|  |  | 
|  | Canonical Triplet info: | 
|  | mingw.org MinGW:    i686-pc-mingw32 | 
|  | mingw-w64 64bit:    x86_64-pc-mingw32   (obsolete triplet) | 
|  | x86_64-w64-mingw32  (preferred triplet) | 
|  | mingw-w64 32bit:    i686-pc-mingw32     (mingw.org compatibility mode) | 
|  | i686-w64-mingw32    (preferred triplet) | 
|  |  | 
|  | == Host Support Libraries == [HOSTLIB] | 
|  |  | 
|  | These libraries are used by GCC on the "host" side. It means that these | 
|  | should be built for the system that will run the newly built GCC. | 
|  |  | 
|  | === The GNU MP Bignum Library (GMP) === [BGMPLIB] | 
|  |  | 
|  | Homepage:               <http://gmplib.org/> | 
|  | Depends on:             None | 
|  | Depended by:            MPC, MPFR, PPL, CLooG | 
|  | GCC dependency type:    Hard (GCC won't build without it) | 
|  |  | 
|  | GMP is primarily written in C and assembly, but it comes with C++ bindings. | 
|  | The asm part is selected by the $host_cpu detected by configure. If your | 
|  | platform is not detected properly, you can use --host=none-none-none to | 
|  | disable asm optimizations. Be sure to set the correct CC, CXX, NM, RANLIB | 
|  | and AR variables. | 
|  |  | 
|  | The C++ bindings are not built by default, but it is required by PPL. To fix | 
|  | this, use "--enable-cxx" and "CPPFLAGS=-fexceptions". PPL needs the | 
|  | -fexceptions part to throw exceptions properly, but it is not strictly | 
|  | required. | 
|  |  | 
|  | On Windows hosts, only static or shared builds can be used at a time, but not | 
|  | both. This is reasoned by the incompatible header set used by static/shared | 
|  | builds. If you do use static builds, you should build any libs that depend on | 
|  | it as static to prevent accidentally exporting GMP symbols in other dlls. | 
|  |  | 
|  | === MPFR === [BMPFRLB] | 
|  |  | 
|  | Homepage:               <http://www.mpfr.org/> | 
|  | Depends on:             GMP | 
|  | Depended by:            None | 
|  | GCC dependency type:    Hard (GCC won't build without it) | 
|  |  | 
|  | MPFR isn't particularly fussy about configure options, so the usual: | 
|  | ./configure | 
|  | make | 
|  | make install | 
|  | is fine. | 
|  |  | 
|  | === Multiprecision (MPC) === [BMPCLIB] | 
|  |  | 
|  | Homepage:               <http://www.multiprecision.org/> | 
|  | Depends on:             GMP | 
|  | Depended by:            None | 
|  | GCC dependency type:    Hard (GCC won't build without it) | 
|  |  | 
|  | MPC isn't particularly fussy about configure options, so the usual: | 
|  | ./configure | 
|  | make | 
|  | make install | 
|  | is fine. | 
|  |  | 
|  | === The Parma Polyhedra Library (PPL) === [BPPLLIB] | 
|  |  | 
|  | Homepage: <http://www.cs.unipr.it/ppl/> | 
|  | Depends on:     GMP | 
|  | Depended by:    ClooG | 
|  | GCC dependency type: None (GCC does not use it directly) | 
|  |  | 
|  | PPL requires that GMP be built with C++ bindings (--enable-cxx) and | 
|  | -fexceptions (to allow exceptions to be thrown across GMP). | 
|  |  | 
|  | === The Clunky Loop Generator (PPL port) === [BCLGLIB] | 
|  |  | 
|  | Homepage: <http://repo.or.cz/w/cloog-ppl.git> | 
|  | Depends on:             GMP, PPL | 
|  | Depended by:            None | 
|  | GCC dependency type:    Soft (GCC can build without it) | 
|  | If you are planning to use CLooG with static PPL, remeber to add | 
|  | '--with-host-libstdcxx="-lstdc++ -lsupc++"' to configure. | 
|  | CLooG needs to be told to use the PPL backend, so use: | 
|  | ./configure --with-ppl=<PPL install prefix> | 
|  | make | 
|  | make install | 
|  |  | 
|  | == Target Support Libraries == [TGTSPLB] | 
|  |  | 
|  | Target support libraries are for use with mingw-w64 itself. It should not | 
|  | be used by the host directly. Hence the target libs will need to be compiled | 
|  | with a compiler targeting mingw-w64. | 
|  |  | 
|  | === pthreads-win32 === [PTHRW32] | 
|  | Homepage: <http://sourceware.org/pthreads-win32/> | 
|  | Depends on:             None | 
|  | Depended by:            None | 
|  | GCC dependency type:    Soft (Required for GCC libgomp support) | 
|  |  | 
|  | Download instructions: | 
|  | cvs -d :pserver:anoncvs@sourceware.org:/cvs/pthreads-win32 login | 
|  | {enter ``anoncvs'' for the password} | 
|  | cvs -d :pserver:anoncvs@sourceware.org:/cvs/pthreads-win32 checkout pthreads | 
|  |  | 
|  | Patch: <http://sourceware.org/ml/pthreads-win32/2009/msg00030/w64sup.patch> | 
|  |  | 
|  | Note: pthreads-win32 does not come with a autotools based build system. It | 
|  | uses a Makefile "GNUmakefile" to build the pthreads dll. | 
|  |  | 
|  | Note: To allow win64 support, apply the patch from the mailing list. | 
|  |  | 
|  | General Build and install instructions: | 
|  | Step 1) type "make clean GC CROSS=x86_64-w64-mingw32-" | 
|  | Note: The CROSS variable specifies your win64/win32 toolchain | 
|  | triplet prefix. To prevent dll clobbering by 32bit/64bit | 
|  | builds having the same names, you can edit GC_DLL in the | 
|  | GNUmakefile (line 440) to produce differently named dlls | 
|  | based on its "bitness" | 
|  | (eg. pthreadGC2-64.dll, pthreadGC2-32.dll). | 
|  | Step 2) copy pthreadGC2.dll (or $GC_DLL) to your path | 
|  | Step 3) Install the lib by copying pthreadGC2.dll as libpthread.a to | 
|  | your GCC libdir (eg. PREFIX/x86_64-w64-mingw32/lib) | 
|  | Step 4) Copy pthread.h, sched.h and semaphore.h to the GCC include dir | 
|  | (eg. PREFIX/x86_64-w64-mingw32/include) | 
|  | Step 5) Edit the pthread.h in your include dir and change the following | 
|  | section from: | 
|  | ======================================================================= | 
|  | #if HAVE_CONFIG_H | 
|  | #include "config.h" | 
|  | #endif /* HAVE_CONFIG_H */ | 
|  | ======================================================================= | 
|  | to: | 
|  | ======================================================================= | 
|  | /* #if HAVE_CONFIG_H */ | 
|  | #include "pconfig.h" | 
|  | /* #endif HAVE_CONFIG_H */ | 
|  | ======================================================================= | 
|  | This is needed to prevent conflicts with other autotools based packages | 
|  | that actually use "config.h" for options. | 
|  | Step 6) Copy the pthread-win32 config.h to your include dir as pconfig.h | 
|  |  | 
|  | 32bit build instructions (assuming mutilib 64bit default GCC) | 
|  | * Edit the GNUmakefile, and change: | 
|  | ======================================================================= | 
|  | AR      = $(CROSS)ar | 
|  | DLLTOOL = $(CROSS)dlltool | 
|  | CC      = $(CROSS)gcc | 
|  | CXX     = $(CROSS)g++ | 
|  | RANLIB  = $(CROSS)ranlib | 
|  | RC      = $(CROSS)windres | 
|  | ======================================================================= | 
|  | to | 
|  | ======================================================================= | 
|  | AR      = $(CROSS)ar | 
|  | DLLTOOL = $(CROSS)dlltool -m i386 | 
|  | CC      = $(CROSS)gcc -m32 | 
|  | CXX     = $(CROSS)g++ -m32 | 
|  | RANLIB  = $(CROSS)ranlib | 
|  | RC      = $(CROSS)windres -F pe-i386 | 
|  | ======================================================================= | 
|  | * You can also use a patch for 32bit builds such as | 
|  | <http://mingw-w64.pastebin.com/pastebin.php?dl=f7b38df38> | 
|  | * Next, follow the General Build and install instructions | 
|  |  | 
|  | == Building the Multilib Cross MinGW-w64 GCC the lazy way == | 
|  | (With ADA support and libgomp)                        [LAZYW64] | 
|  |  | 
|  | Its a lazy method because it involves building GCC with all enabled | 
|  | front ends only once, without restarting the cross GCC build. | 
|  |  | 
|  | First of all, your host compiler (native system "gcc") must support ADA. | 
|  | If your platform does not have GNAT binaries, use the binaries from: | 
|  | <https://libre.adacore.com/libre/download/> | 
|  |  | 
|  | If you do not want ADA support, or confident about your host ADA support, | 
|  | you can skip the ADA bootstrap phase. | 
|  |  | 
|  | === ADA Bootstrap Phase === [ADABOOT] | 
|  |  | 
|  | Bootstrapping ADA is needed if ADA is to be supported by the mingw-w64 | 
|  | cross GCC. | 
|  |  | 
|  | To begin bootstrap ADA, you must grab the GCC source that will be used | 
|  | for the mingw-w64 cross GCC, so that the ADA support is as close as | 
|  | possible with the target GCC version. | 
|  |  | 
|  | Use the source to build a native compiler for your host machine. You must | 
|  | enable at least C, ADA, and C++ support. It is advisable to prefix | 
|  | (i.e. using --prefix=/opt/test) the entire native bootstrap toolchain | 
|  | in order to avoid overwriting the compiler provided by your host system. | 
|  | You should also build a prefixed native Binutils for use with the new | 
|  | bootstrap compiler. | 
|  |  | 
|  | Remember to build GCC OUTSIDE its source directory, NOT inside it and | 
|  | certainly NOT in a sub-directory. | 
|  |  | 
|  | === MinGW-w64 cross Binutils === [CRSBINU] | 
|  |  | 
|  | The official method to build the mingw-w64 toolchain is to set --prefix | 
|  | and --with-sysroot to the same directory to allow the toolchain to be | 
|  | relocatable. To make Multilib support possible, you need to use | 
|  | "--enable-targets=x86_64-w64-mingw32,i686-w64-mingw32". | 
|  |  | 
|  | An example configure line for Binutils is: | 
|  | ../path/to/binutils/configure --prefix=<prefix> --with-sysroot=<prefix> \ | 
|  | --enable-targets=x86_64-w64-mingw32,i686-w64-mingw32 \ | 
|  | --host=<build triplet> --build=<build triplet> \ | 
|  | --target=x86_64-w64-mingw32 | 
|  |  | 
|  | === Install mingw-w64 Headers === [MGW64HD] | 
|  |  | 
|  | When you checkout the svn trunk from the mingw-w64 developer repository, there | 
|  | should be a directory called mingw-w64-headers. Install it with: | 
|  | ../path/to/mingw-w64-headers/configure --prefix=<prefix>/x86_64-w64-mingw32 \ | 
|  | --enable-sdk=none --build=<host triplet> --host=x86_64-w64-mingw32 | 
|  | make install | 
|  |  | 
|  | To view the available sdks, use --help. The prefix should be similar to the | 
|  | prefix used for cross Binutils. Although the mingw-w64 cross GCC is not | 
|  | installed yet, configure will not fail it as it only checks the --host option. | 
|  | It is important to set the --host option correctly, failing to do so will | 
|  | cause the cross GCC to fail to find the expected system headers. | 
|  |  | 
|  | === Setup Symlinks === [SETSYML] | 
|  |  | 
|  | Your install root for the mingw-w64 cross toolchain should contain the | 
|  | following directories. Create the directories if missing. It is easier | 
|  | to use "ln -s" softlinks to link directories than to copy them over. | 
|  |  | 
|  | <root>/x86_64-w64-mingw32 | 
|  | <root>/x86_64-w64-mingw32/include [headers previously installed here] | 
|  | <root>/x86_64-w64-mingw32/lib | 
|  | <root>/x86_64-w64-mingw32/lib32 | 
|  | <root>/x86_64-w64-mingw32/lib64 [link to neighbor lib] | 
|  | <root>/mingw [link to x86_64-w64-mingw32] | 
|  | <root>/mingw/include | 
|  | <root>/mingw/lib | 
|  | <root>/mingw/lib32 | 
|  | <root>/mingw/lib64 [link to neighbor lib] | 
|  |  | 
|  | On Windows, you can use "ntfs link" <http://elsdoerfer.name/=ntfslink> | 
|  | to create "junction points" to link directories. These junction points | 
|  | are transparent to user mode applications such as GCC. | 
|  |  | 
|  | Make sure the "mingw" directory mirrors "x86_64-w64-mingw32" exactly. Ditto | 
|  | for "lib64" and "lib" | 
|  |  | 
|  | === Build Core GCC === [BCORGCC] | 
|  |  | 
|  | GCC can be configured in many ways, the following is an example that worked. | 
|  | Make sure to add your cross Binutils binaries to your $PATH before continuing. | 
|  |  | 
|  | If you did use the ADA compiler from adacore to produce a bootstrap ADA | 
|  | compiler, make sure to add the prefix in such a way that it is found | 
|  | before your default host compiler. | 
|  | (i.e. export PATH=/opt/adaboot/bin:$PATH:/mingw64/path/bin) | 
|  |  | 
|  | Some of the configure options do not sound possible with a stage-1 cross, | 
|  | but be assured that it has been tested. | 
|  |  | 
|  | Remember to build GCC OUTSIDE its source directory, NOT inside it and certainly | 
|  | NOT in a sub-directory. | 
|  |  | 
|  | Example: | 
|  | ../gcc-trunk/configure --{host,build}=<build triplet> \ | 
|  | --target=x86_64-w64-mingw32 --enable-multilib --enable-64bit \ | 
|  | --{prefix,with-sysroot}=<prefix> --enable-version-specific-runtime-libs \ | 
|  | --enable-shared --with-dwarf --enable-fully-dynamic-string \ | 
|  | --enable-languages=c,ada,c++,fortran,objc,obj-c++ --enable-libgomp \ | 
|  | --enable-libssp --with-host-libstdcxx="-lstdc++ -lsupc++" \ | 
|  | --with-{gmp,mpfr,mpc,cloog,ppl}=<host dir> --enable-lto | 
|  |  | 
|  | Explanation: | 
|  | --enable-version-specific-runtime-libs | 
|  | Installs libgcc/libstdc++ and other target support libraries in such a | 
|  | way that multiple GCC installs can coexist simultaneously. | 
|  |  | 
|  | --enable-shared | 
|  | Builds shared support libraries | 
|  |  | 
|  | --with-dwarf | 
|  | Use Dwarf debugging format by default | 
|  |  | 
|  | --enable-fully-dynamic-string | 
|  | Enable dynamic std::string class to work around lazy initialization. | 
|  |  | 
|  | --enable-libgomp | 
|  | Enable OpenMP support, it is not enabled by default on MinGW platforms. | 
|  | Requires pthreads-win32 (target) installed. | 
|  |  | 
|  | --enable-libssp | 
|  | Enable Stack Smash Protection, a buffer overrun detector. | 
|  |  | 
|  | --with-host-libstdcxx | 
|  | Lists down the C++ support libraries to link with. This is useful | 
|  | when using static PPL and CLooG. | 
|  |  | 
|  | --with-{gmp,mpfr,mpc,cloog,ppl}=<host dir> | 
|  | Tells GCC where the host support libraries are installed to. | 
|  | (i.e. search <host dir>/include & <host dir>/lib) | 
|  |  | 
|  | --enable-lto | 
|  | Enables Link Time Optimization support. | 
|  |  | 
|  | Use "make all-gcc" to build the standalone GCC compiler without target | 
|  | support libs. Install it with "make install-gcc". | 
|  |  | 
|  | Remember, this is a standalone gcc, it won't actually be able to link | 
|  | executables, but it is already suitable to compile the CRT. | 
|  |  | 
|  | Do not delete the GCC build directory, we can continue later. | 
|  |  | 
|  | === Build the mingw-w64 CRT === [BMGWCRT] | 
|  |  | 
|  | When you checkout the svn trunk from the mingw-w64 developer repository, there | 
|  | should be a directory called mingw-w64-crt. | 
|  | Example configure: | 
|  | ../path/to/crt/configure --prefix=<prefix>/x86_64-w64-mingw32 --enable-lib32 \ | 
|  | --enable-lib64 --build=<build triplet> --host=x86_64-w64-mingw32 | 
|  |  | 
|  | Explanation: | 
|  | --enable-lib32 | 
|  | If you enabled multilib support in x86_64-w64-mingw32-gcc, this will build | 
|  | 32bit libs for use with win32 programming. For $host_cpu i686-w64-mingw32, | 
|  | it is enabled by default. | 
|  |  | 
|  | --enable-lib64 | 
|  | Enable building 64bit libs for use with win64 programming. For $host_cpu | 
|  | x86_64-w64-mingw32, it is enabled by default. | 
|  |  | 
|  | Once the configure ends successfully, run "make && make install". | 
|  |  | 
|  | If you used symlinks or ntfs junction points to link the "lib*" directories, | 
|  | you should be fine. If you manually copied x86_64-w64-mingw32 to mingw, you | 
|  | must copy the "lib*" directories so that "lib64" mirrors "lib" and | 
|  | "lib32" in "mingw" mirrors "x86_64-w64-mingw32/lib32" | 
|  |  | 
|  | === Build libgcc === [BLIBGCC] | 
|  |  | 
|  | Reenter the build directory used earlier in [BCORGCC], and issue | 
|  | "make all-target-libgcc", then "make install-target-libgcc". | 
|  |  | 
|  | This will install libgcc. As of writing, there is a minor bug when | 
|  | --enable-version-specific-runtime-libs is used, libgcc_s.a is | 
|  | installed incorrectly. | 
|  |  | 
|  | Move it from: | 
|  | <prefix>/lib/gcc/<arch>/lib32/libgcc_s.a to | 
|  | <prefix>/lib/gcc/<arch>/<version>/32/libgcc_s.a | 
|  | and | 
|  | <prefix>/lib/gcc/<arch>/lib64/libgcc_s.a to | 
|  | <prefix>/lib/gcc/<arch>/<version>/libgcc_s.a | 
|  |  | 
|  | The libgcc dll is also clobbered during install, search the build | 
|  | directory for the dll and install it to separate directories as you | 
|  | see fit. Make sure 32bit apps only see the 32bit variant, same for | 
|  | 64bit apps. | 
|  |  | 
|  | === Build pthreads === [BPTHR32] | 
|  |  | 
|  | pthread-win32 is required for libgomp to work. Now that the CRT and | 
|  | libgcc is installed, we can proceed with building the pthread dll. | 
|  |  | 
|  | Please refer to the pthreads-win32 section [PTHRW32] for instructions. | 
|  | Make sure to build for both win32 and win64 variants. | 
|  |  | 
|  | === Continue the build === [CTNTBLD] | 
|  |  | 
|  | Reenter the build directory used earlier in [BCORGCC] and continue | 
|  | the build with "make". Finally, install with "make install". | 
|  |  |