Category Archives: gcc

Building GCC MinGW Toolchain Cross Compiler

Windows, up until today, is still popular Operating System and have large market. This Microsoft’s product is designed for end-user and reducing complexity of Operating System. Even when some other OS such as Linux and Mac OS starts invading, this Operating System is still major and fanatically used by some people in the world.

In this article we will about how to build GCC Win32 and Win64 Toolchain for Win32 and Win64 architecture, which is a cross compiler to build Win32 and Win64 program.

Requirement set for this article:

    1. GCC (Native platform)
    2. Binutils (Native platform)
    3. Bison
    4. Flex
    5. gperf

CoreutilsMake (>= 3.8.1)

  1. SVN & CVS client

Also the test is done on Slackware64 current, though it is optional. You can use other Linux distribution which suit you.

While the previous list is requirement on your host system (your system which will build the cross compiler), we have another list. Some of the component mentioned below will be taken out from their respective repository.

  1. MinGW-w64 (SVN repository)
  2. GCC 4.9.2
  3. Binutils 2.24
  4. GDB 7.8.1
  5. GMP 6.0.0
  6. MPFR 3.1.2
  7. MPC 1.0.2

The Target

There are two architecture: Win32 and Win64. You are free to choose what MinGW system you will build. However, in this article, we will build MinGW Cross Compiler for Windows 64-bit. If you read other cross compiler article, we need a target alias (or simply target) which is the target of the toolchain.

Preparation

We will need some disk space (~2GB should be enough). We also need root access to install it on “system-wide”.

We will create a working directory. We will refer it as $MINGWGCC, so $MINGWGCC/src should really be something like ~/MINGWGCC/src (the ~ means your home directory). So go ahead and create following directory structure:

# set aliases
export MINGWGCC=~/
export PREFIX=/usr/local
export BUILD=$(gcc -dumpmachine)
export TARGET=x86_64-w64-mingw32

export BINUTILS_BUILD=${MINGWGCC}/build/binutils-build
export GCC_BUILD=${MINGWGCC}/build/gcc-build
export GDB_BUILD=${MINGWGCC}/build/gdb-build
export MINGW_BUILD=${MINGWGCC}/build/mingw-build
export MINGW_H_BUILD=${MINGWGCC}/build/mingw-h-build

export BINUTILS_SRC=${MINGWGCC}/src/binutils-2.24
export GCC_SRC=${MINGWGCC}/src/gcc-4.9.2
export GDB_SRC=${MINGWGCC}/src/gdb-7.8.1
export MINGW_SRC=${MINGWGCC}/src/mingw/
export MINGW_HEADERS=${MINGW_SRC}/mingw-w64-headers

# make base dir, original archives dir (orig), source code dir (src), 
# and working / building dir (build) 
mkdir ${MINGWGCC}{,/{orig,src,build}}

# Make build directory for each component
mkdir ${MINGWGCC}/build/{binutils,gcc,gdb,mingw{,-h}}-build

Acquiring the Materials

A cross compiler for Win32 and Win64 are provided by MinGW-w64 project. Download latest packages of GCC, GDB, binutils, and MinGW-w64 source code. You can download it using wget or alternatively download via browser and move it to $MINGWGCC/orig.

cd ${MINGWGCC}/orig

wget ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.9.2/gcc-4.9.2.tar.bz2
wget ftp://ftp.gnu.org/pub/gnu/gdb/gdb-7.8.1.tar.xz
wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2

wget ftp://ftp.gnu.org/pub/gnu/gmp/gmp-6.0.0a.tar.xz
wget ftp://ftp.gnu.org/pub/gnu/mpc/mpc-1.0.2.tar.gz
wget ftp://ftp.gnu.org/pub/gnu/mpfr/mpfr-3.1.2.tar.gz

Then, extract them to src directory.

cd ${MINGWGCC}/src

tar -jxf ${MINGWGCC}/orig/gcc-4.9.2.tar.bz2
tar -Jxf ${MINGWGCC}/orig/gdb-7.8.1.tar.xz
tar -jxf ${MINGWGCC}/orig/binutils-2.24.tar.bz2

Next, the MinGW and GCC codes.

cd ${MINGWGCC}/src
svn co 'https://svn.code.sf.net/p/mingw-w64/code/trunk' mingw

Next we need to download some prerequisites, especially GMP (GNU Multiple Precision), MPC (Multiple-Precision Complex), and MPFR (Multiple-Precision Floating Point Reliably) which is used for computation. The prerequisites can be downloaded by invoking following command:

The MPFR, GMP, and MPC is not the latest version, but at least we can build GCC. Suppose your working directory at /home/xathrya/ARMGCC, to obtain MPDR, GMP, and MPC invoke following command:

cd ${GCC_SRC}
./contrib/download_prerequisites

However, the version of GMP, MPC, and MPFR is not the latest version. We can switch to the latest version by download the latest version and create symbolic link to it.

cd ${GCC_SRC}

rm {gmp,mpc,mpfr}

tar -Jxf ${MINGWGCC}/orig/gmp-6.0.0a.tar.xz
tar -zxf ${MINGWGCC}/orig/mpc-1.0.2.tar.gz
tar -zxf ${MINGWGCC}/orig/mpfr-3.1.2.tar.gz

ln -s gmp-6.0.0 gmp
ln -s mpc-1.0.2 mpc
ln -s mpfr-3.1.2 mpfr

Building the Toolchains

Building stage is pretty simple. Honestly speaking, the tricky part is about how GCC and built concept and ordering them in correct order.

Binutils

First, built binutils. This will provide lots of useful tools in building MinGW libraries and binaries (like objdump, ld, ranlib, etc). Invoke following commands:

cd ${BINUTILS_BUILD}
${BINUTILS_SRC}/configure 
   --target=${TARGET} 
   --enable-targets=x86_64-w64-mingw32,i686-w64-mingw32 
   --prefix=${PREFIX} 
   --disable-nls
make -j4 all
make install
make clean

MinGW Headers

MinGW headers is set of headers used to build MinGW application. It is different beast with Linux GCC headers, although we use the same vendor compiler.

cd ${MINGW_H_BUILD}
${MINGW_HEADERS}/configure 
    --build=${BUILD} 
    --host=${TARGET} 
    --prefix=${PREFIX}/${TARGET}
make install

For v3 and later trunk, we have to append ${TARGET} to our prefix. If not, your native GCC will be contaminated. Please note it.

This will install MinGW headers into ${PREFIX}/${TARGET}/include/ or in our case it would be /usr/local/x86_64-w64-mingw32/include/.

MinGW Directories and Symlinks

We should end up with a ${PREFIX}/${TARGET}/ directory. Manually create lib/ directory and create symbolic link as lib64/

GCC also requires the ${TARGET} directory to be mirrored as a directory ‘mingw’ in the same root (it’s ${PREFIX} directory). Therefore, we need to make a soft link there.

n -s ${PREFIX}/${TARGET} ${PREFIX}/mingw
mkdir -p ${PREFIX}/${TARGET}/lib{,32}
ln -s ${PREFIX}/${TARGET}/lib ${PREFIX}/${TARGET}/lib64

GCC Core

Next we will build the GCC. But please note that we are only intereset on C and C++ so we will ignore other language. To built GCC, do this:

cd ${GCC_BUILD}
${GCC_SRC}/configure 
   --build=${BUILD} 
   --target=${TARGET} 
   --enable-targets=all 
   --prefix=${PREFIX} 
   --enable-interwork 
   --enable-multilib 
   --enable-languages="c,c++" 
   --enable-shared 
   --enable-fully-dynamic-string 
   --with-system-zlib 
   --disable-nls
make -j4 all-gcc install-gcc
make clean

C RunTime (CRT) Library

 Next we will build the C runtime library or the MinGW itself. In the short: building libs required. The static and dynamic lib built with GCC core we have built.

cd ${MINGW_BUILD}
${MINGW_SRC}/configure 
    --host=${TARGET} 
    --prefix=${PREFIX}/${TARGET} 
    --enable-multilib 
    --enable-shared 
    --enable-lib32
make -j4 all
make install

For v3 and later trunk, we have to append ${TARGET} to our prefix. If not, your native GCC will be contaminated. Please note it.

Make sure you have following directories in the ${PREFIX}:

# ${PREFIX} => /usr/local
# ${TARGET} => x86_64-w64-mingw32

${PREFIX}/${TARGET}
${PREFIX}/${TARGET}/include
${PREFIX}/${TARGET}/lib
${PREFIX}/${TARGET}/lib32
${PREFIX}/${TARGET}/lib64 [link to lib]
${PREFIX}/mingw [link to ${TARGET}]
${PREFIX}/mingw/include
${PREFIX}/mingw/lib
${PREFIX}/mingw/lib32
${PREFIX}/mingw/lib64 [link to lib]

GCC (again)

Now that we have our runtime libraries, go back and ginish the GCC build:

cd ${GCC_BUILD}
make -j4
make install

GDB

Optionally you can build GDB. To do so, invoke following:

cd ${GDB_BUILD}
${GDB_SRC}/configure 
   --target=${TARGET} 
   --prefix=${PREFIX} 
   --enable-interwork 
   --enable-multilib
make -j4 all 
make install

And that’s it. You should have them now.

Testing

The toolchain can be tested with the minimal code here, save as demo.c:

int main()
{
   return 0;
}

void exit(int code)
{
   while(1);
}

Invoke following command to compile:

x86_64-w64-mingw32-gcc demo.c -o demo.exe

Building GCC AVR Toolchain Cross Compiler

In this article we will about how to build GCC AVR Toolchain, which is a cross compiler to build AVR program. The built GCC can be used to compile application into AVR’s machine codes. The toolchain then reside on /usr/local path.

For this article, I use:

  1. Slackware64 14.0
  2. GCC 4.9.0
  3. GDB 7.7
  4. Binutils 2.24
  5. AVR-libc 1.8
  6. GMP 6.0.0
  7. MPFR 3.1.2
  8. MPC 1.0.2

Preparation

We will need some disk space (~2GB should be enough). We also need root access to install it on “system-wide”.

Slackware64 14.0 is optional. You can use any linux distribution you like.

We will create a working directory. We will refer it as $AVRGCC, so $AVRGCC/src should really be something like ~/AVRGCC/src (the ~ means your home directory). So go ahead and create following directory structure:

# set aliases
export AVRGCC=~/AVRGCC
export TARGET=avr
export PREFIX=/usr/local

export BINUTILS_BUILD=${AVRGCC}/build/binutils-build
export GCC_BUILD=${AVRGCC}/build/gcc-build
export GDB_BUILD=${AVRGCC}/build/gdb-build

export BINUTILS_SRC=${AVRGCC}/src/binutils-2.24
export GCC_SRC=${AVRGCC}/src/gcc-4.9.0
export GDB_SRC=${AVRGCC}/src/gdb-7.7
export AVRLIBC_SRC=${AVRGCC}/src/avr-libc-1.8.0

# make base dir, original archives dir (orig), source code dir (src), 
# and working / building dir (build) 
mkdir ${AVRGCC}{,/{orig,src,build}}

# Make build directory for each component
mkdir ${AVRGCC}/build/{binutils,gcc,gdb}-build

Acquiring the Materials

Download latest packages of GCC, GDB, binutils, and Newlib.You can download it using wget or alternatively download via browser and move it to $AVRGCC/orig. The version we will use is GCC 4.9.0, GDB 7.7, binutils 2.24, and newlib 2.1.0.

cd ${AVRGCC}/orig
wget ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.9.0/gcc-4.9.0.tar.bz2
wget ftp://ftp.gnu.org/pub/gnu/gdb/gdb-7.7.tar.bz2
wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2
wget ftp://ftp.twaren.net/Unix/NonGNU//avr-libc/avr-libc-1.8.0.tar.bz2

wget ftp://ftp.gnu.org/pub/gnu/gmp/gmp-6.0.0a.tar.xz
wget ftp://ftp.gnu.org/pub/gnu/mpc/mpc-1.0.2.tar.gz
wget ftp://ftp.gnu.org/pub/gnu/mpfr/mpfr-3.1.2.tar.gz

Then, extract them to src directory.

cd ${AVRGCC}/src

tar -jxf ${AVRGCC}/orig/gcc-4.9.0.tar.bz2
tar -jxf ${AVRGCC}/orig/gdb-7.7.tar.bz2
tar -jxf ${AVRGCC}/orig/binutils-2.24.tar.bz2
tar -jxf ${AVRGCC}/orig/avr-libc-1.8.0.tar.bz2

Next we need to download some prerequisites, especially GMP (GNU Multiple Precision), MPC (Multiple-Precision Complex), and MPFR (Multiple-Precision Floating Point Reliably) which is used for computation. The prerequisites can be downloaded by invoking following command:

The MPFR, GMP, and MPC is not the latest version, but at least we can build GCC. Suppose your working directory at /home/xathrya/AVRGCC, to obtain MPDR, GMP, and MPC invoke following command:

cd ${GCC_SRC}
./contrib/download_prerequisites

However, the version of GMP, MPC, MPFR are not the latest version. We can switch to the latest version by link it to our downloaded one.

cd ${GCC_SRC}

rm {gmp,mpc,mpfr}

tar -Jxf ${AVRGCC}/orig/gmp-6.0.0a.tar.xz
tar -zxf ${AVRGCC}/orig/mpc-1.0.2.tar.gz
tar -zxf ${AVRGCC}/orig/mpfr-3.1.2.tar.gz

ln -s gmp-6.0.0 gmp
ln -s mpc-1.0.2 mpc
ln -s mpfr-3.1.2 mpfr

Building the Toolchains

Building stage is pretty simple. Honestly speaking, the tricky part is about how GCC and built concept and ordering them in correct order.

Binutils

First, built binutils. This will provide lots of useful tools in building ARM libraries and binaries (like objdump, ld, ranlib, etc). Invoke following commands:

cd ${BINUTILS_BUILD}
${BINUTILS_SRC}/configure --target=${TARGET} --prefix=${PREFIX} 
    --enable-interwork --enable-multilib --enable-shared 
make configure-host
make -j4 all
make install

You will notice a few configure options that are really critical for getting things to work properly.

  • –target=avr Says we want a compiler to generate binaries for the avr platform.
  • –enable-multilib Multilib allows the use of libraries that are compiled multiple times for different targets/build types
  • –enable-shared – enable the creation of the shared libraries.

GCC

Next we will build the GCC. But please note that we are only intereset on C and C++ so we will ignore other language. To built GCC, do this:

cd ${GCC_BUILD}
${GCC_SRC}/configure --target=${TARGET} --prefix=${PREFIX} --enable-interwork 
   --enable-multilib --enable-languages="c,c++" --with-dwarf2 --disable-libssp 
   --enable-c99 --enable-long-long --enable-__cxa_atexit --enable-shared
make -j4 all-gcc 
make -j4 all-target-libgcc

make install-gcc install-target-libgcc

Now, the important points are:

  • –enable-languages=”c,c++” - means build C and C++ only.
  • –with-headers – this adds a header inlude path during build time and will allow the build to find the newlib header files
  • –enable-__cxa_atexit – allows use of __cxa_atexit, rather than atexit, to register C++ destructors for local statics and global objects and is essential for fully standards-compliant handling of destructors. It also affects the C++ ABI and therefore results in C++ shared libraries and C++ programs that are interoperable with other Linux distributions.
  • –enable-c99 – enable C99 support for C programs.
  • –enable-long-long – enables long long support in the compiler.

avr-libc

Now build our avr-libc

cd ${AVRLIBC_SRC}
./configure --host=avr --build=`./config.guess` --prefix=${PREFIX}
make
make install

GDB

Optionally you can build GDB. To do so, invoke following:

cd ${GDB_BUILD}
${GDB_SRC}/configure --target=${TARGET} --prefix=${PREFIX} 
  --enable-interwork --enable-multilib
make -j4 all 
make install

And that’s it. You should have them now.

Testing

The toolchain can be tested with the minimal code here:

int main()
{
   return 0;
}