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 2010-01-03 1.1 Jonathan Yong 2010-05-18 1.11 Jonathan Yong 2010-08-31 1.12 Jonathan Yong 2013-01-27 1.13 Jonathan Yong == 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: 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: 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: 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: 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: 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= 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: 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: 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 * 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: 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= --with-sysroot= \ --enable-targets=x86_64-w64-mingw32,i686-w64-mingw32 \ --host= --build= \ --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=/x86_64-w64-mingw32 \ --enable-sdk=none --build= --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. /x86_64-w64-mingw32 /x86_64-w64-mingw32/include [headers previously installed here] /x86_64-w64-mingw32/lib /x86_64-w64-mingw32/lib32 /x86_64-w64-mingw32/lib64 [link to neighbor lib] /mingw [link to x86_64-w64-mingw32] /mingw/include /mingw/lib /mingw/lib32 /mingw/lib64 [link to neighbor lib] On Windows, you can use "ntfs link" 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}= \ --target=x86_64-w64-mingw32 --enable-multilib --enable-64bit \ --{prefix,with-sysroot}= --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}= --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}= Tells GCC where the host support libraries are installed to. (i.e. search /include & /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=/x86_64-w64-mingw32 --enable-lib32 \ --enable-lib64 --build= --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: /lib/gcc//lib32/libgcc_s.a to /lib/gcc///32/libgcc_s.a and /lib/gcc//lib64/libgcc_s.a to /lib/gcc///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".