Building Binutils & GCC in the MinGW VM

Now it's time to replace bootstrapping compiler with full-featured compiler tied to glibc and capable of building hosted code, not only freestanding code. Also new compiler will be independent from cygwin1.dll, unlike the old one.

  1. Run the following commands (replicate usr subfolders to "target triplet" subfolders):
    # cd /opt/crosstool/gcc-4.9.2-glibc-2.19/i586-linux-gnu/
    # cp -R usr/include i586-linux-gnu/include
    # cp -R i586-linux-gnu/lib/ldscripts usr/lib/ldscripts
    # cp -R usr/lib/* i586-linux-gnu/lib
    # cd ../x86_64-linux-gnu/
    # cp -R usr/include x86_64-linux-gnu/include
    # cp -R x86_64-linux-gnu/lib/ldscripts usr/lib64/ldscripts
    # cp -R usr/lib64/* x86_64-linux-gnu/lib
  2. Update C:\MinGW\msys\1.0\opt\crosstool\src\build_gcc_cross.sh :

    #!/bin/bash
    
    export PATH=.:/usr/local/bin:/mingw/bin:/bin
    export PATH=$PATH:/c/WINDOWS/system32:/c/WINDOWS
    export PATH=$PATH:/c/WINDOWS/System32/Wbem
    export TARGET=i586-linux-gnu
    export PREFIX=/opt/crosstool/gcc-4.9.2-glibc-2.19/$TARGET
    
    cd /opt/crosstool/src/build-binutils
    find . -delete
    LDFLAGS="-Wl,-s -Wl,-static -static -static-libgcc" \
      ../binutils-2.25/configure --target=$TARGET \
        --prefix=$PREFIX --with-sysroot=$TARGET \
        --disable-nls
    if [ "$?" -ne "0" ]; then
        echo "=== build script: failed to configure binutils ==="
        exit 1
    fi
    make all
    if [ "$?" -ne "0" ]; then
        echo "=== build script: failed to make binutils ==="
        exit 1
    fi
    make install
    if [ "$?" -ne "0" ]; then
        echo "=== build script: failed to install binutils ==="
        exit 1
    fi
    
    export PATH=$PATH:$PREFIX/bin
    cd /opt/crosstool/src/build-gcc
    find . -delete
    LDFLAGS="-Wl,-s -Wl,-static -static -static-libgcc" \
      ../gcc-4.9.2/configure --target=$TARGET --prefix=$PREFIX \
         --with-sysroot=$PREFIX --with-arch=i586 \
         --disable-sjlj-exceptions --enable-checking=release \
         --enable-linker-build-id --enable-gnu-unique-object \
         --disable-nls --enable-languages=c,c++ \
         --with-headers --enable-shared --enable-threads=posix \
         --disable-multilib -enable-__cxa_atexit \
         --disable-fixed-point \
         --disable-libmudflap --disable-libssp \
         --disable-libgomp --without-ppl --without-cloog \
         --with-gmp=/usr/local --with-mpfr=/usr/local \
         --with-mpc=/usr/local
    if [ "$?" -ne "0" ]; then
        echo "=== build script: failed to configure gcc ==="
        exit 1
    fi
    make
    if [ "$?" -ne "0" ]; then
        echo "=== build script: failed to make gcc ==="
        exit 1
    fi
    make install
    if [ "$?" -ne "0" ]; then
        echo "=== build script: failed to install gcc ==="
        exit 1
    fi
    
    echo "=== build script: OK ==="
    

  3. Put C-style comments /* */ around "#define caddr_t char *" line in C:\MinGW\msys\1.0\opt\crosstool\src\gcc-4.4.1\gcc\configure to prevent caddr_t-related error in sys/types.h during GCC build.
  4. Run C:\MinGW\msys\1.0\opt\crosstool\src\build_gcc_cross.cmd and wait until it completes.
  5. If there are no errors, shutdown the MinGW VM and make snapshot "SNAP-D".

Notes:

  • There may be an error in $TARGET/usr/include/sys/types.h when building GCC (in the line "typedef __caddr_t caddr_t;"). Reason: you forgot to patch GCC configure script as described above.
  • Multilib is a special feature of GCC to allow building 32-bit targets on x86_64 platform. We don't use that one; we build two distinct cross-compilers instead.
  • LDFLAGS="-Wl,-s -Wl,-static -static -static-libgcc" option prevents dynamic linking to libgcc_s_dw2-1.dll (runtime library of MinGW) and also automatically strips EXE files at build time.
  • If you didn't specify --with-sysroot=$PREFIX configure argument, you will get the following error during build:

    In file included from ../../../gcc-4.9.2/libgcc/../gcc/libgcc2.c:29:0:
    ../../../gcc-4.9.2/libgcc/../gcc/tsystem.h:87:19: fatal error: stdio.h: No such file or directory
    compilation terminated.
    make[2]: *** [_muldi3.o] Error 1
    make[2]: Leaving directory `/opt/crosstool/src/build-gcc/arm-linux-gnueabihf/libgcc'
    make[1]: *** [all-target-libgcc] Error 2
    make[1]: Leaving directory `/opt/crosstool/src/build-gcc'
    make: *** [all] Error 2
     
  • If you didn't replicate usr subfolders to "target triplet" subfolders as explained above, then you will get the following error:
    checking how to run the C preprocessor... /lib/cpp
    configure: error: in `/opt/crosstool/src/build-gcc/i586-linux-gnu/libgcc':
    configure: error: C preprocessor "/lib/cpp" fails sanity check
    See `config.log' for more details.
    make[1]: *** [configure-target-libgcc] Error 1
    make[1]: Leaving directory `/opt/crosstool/src/build-gcc'
    make: *** [all] Error 2
    and in /opt/crosstool/src/build-gcc/libgcc/config.log:

    C:/MinGW/msys/1.0/opt/crosstool/src/build-gcc/gcc/include-fixed/limits.h:168:61: error: no include path in which to search for limits.h

    and further in /opt/crosstool/src/build-gcc/libgcc/config.log:

    conftest.c:12:0: fatal error: assert.h: No such file or directory

  • If you didn't specify --disable-fixed-point configure option, you will get the following errors during build:
    C:\MinGW\msys\1.0\bin\make.exe: *** couldn't commit memory
    for cygwin heap, Win32 error 487
    make[1]: *** [all-target-libgcc] Error 1
    make[1]: Leaving directory `/opt/crosstool/src/build-gcc'
    make: *** [all] Error 2
    
    and
    xgcc.exe: error: CreateProcess: No such file or directory
    make[2]: *** [libgcc_s.so] Error 1
    make[2]: Leaving directory `/opt/crosstool/src/build-gcc/arm-linux-gnueabihf/libgcc'
    make[1]: *** [all-target-libgcc] Error 2
    make[1]: Leaving directory `/opt/crosstool/src/build-gcc'
    make: *** [all] Error 2
    
    First one is non-fatal (can be overcomed by re-running `make' command for a 3-4 times), second one is related to exceeding Win32 command line length limit and can't be trivially avoided.

Additional steps to support 64-bit Linux target platform:

  1. Replace TARGET=i586-linux-gnu with TARGET=x86_64-linux-gnu and remove "--with=i586" in build_gcc_cross.sh
  2. Run C:\MinGW\msys\1.0\opt\crosstool\src\build_gcc_cross.cmd and wait until it completes.
  3. If there are no errors, shutdown the MinGW VM and make snapshot "SNAP-E".


>> Read next section or buy already prepared cross-compiler (€10) to save your time.