Motivation

My motivation to start this blog mainly was to have a memory hook for myself.
I'm experiencing to investigate repeatedly on the same problems multiple times in slightly different contexts, when these appear in e.g. new project setup cycles.
May be my markers might also be helpful for other software developers ...

9/11/2013

Building GCC ARM cross toolchain on Suse Linux

I needed to have a GCC 4.7.1 toolchain for ARM (Cortex-M3) with the C++11 standard features.
So I tried following another blog post to compile the toolchain myself. Though, modifications were necessary, here's what to do step by step:

1. Ensure to have the necessary headers & libraries installed
I have used YAST's 'Install Software' feature, to install the following packages that will be necessary to complete all the build steps (just search for the package names, select and accept):
  • gmp-devel
  • mpfr-devel
  • mpc-devel
  • texinfo
  • ncurses-devel
  • termcap

2. Create a directory skeleton


    cd ~
    mkdir arm-none-eabi arm-none-eabi-src
    cd arm-none-eabi
    mkdir src build
    cd ~/arm-none-eabi-src
    mkdir src build

3. Download the the source packages and extract them


    cd ~/arm-none-eabi-src/src

    wget ftp://ftp.gnu.org/gnu/gcc/gcc-4.7.1/gcc-4.7.1.tar.bz2
    wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.22.tar.bz2
    wget ftp://ftp.gnu.org/gnu/gdb/gdb-7.4.tar.bz2
    wget ftp://sources.redhat.com/pub/newlib/newlib-1.20.0.tar.gz

    tar -xf gcc-4.7.1.tar.bz2
    tar -xf binutils-2.22.tar.bz2
    tar -xf gdb-7.4.tar.bz2
    tar -xf newlib-1.20.0.tar.gz

4. Build the binutils


    cd ~/arm-none-eabi-src/build
    mkdir binutils-2.22
    cd binutils-2.22
    ../../src/binutils-2.22/configure \
      --target=arm-none-eabi \
      --prefix=$HOME/arm-none-eabi \
      --with-cpu=cortex-m3 \
      --with-no-thumb-interwork \
      --with-mode=thumb
    make all install
    export PATH="$PATH:$HOME/arm-none-eabi/bin"

5. Build GCC (Part1)


    cd ~/arm-none-eabi-src/build
    mkdir gcc-4.7.1
    cd gcc-4.7.1
    ../../src/gcc-4.7.1/configure --target=arm-none-eabi \
      --prefix=$HOME/arm-none-eabi --with-cpu=cortex-m3 \
      --with-mode=thumb --disable-multilib \
      --with-no-thumb-interwork \
      --enable-languages="c,c++" --with-newlib \
      --with-headers=../../src/newlib-1.20.0/newlib/libc/include
    make all-gcc install-gcc

The --enable-cxx-flags configure option might be additionally used to control the build flags of the libstdc++ (included in this step):

    --enable-cxx-flags='-fno-exceptions \
        -ffunction-sections -fno-omit-frame-pointer'

In general the same C++ compile flags should be used as they'll appear when building the intended target code.

6. Build GCC newlib with the cross compiler (Part2)


    cd ~/arm-none-eabi-src/build
    mkdir newlib-1.20.0
    cd newlib-1.20.0
    ../../src/newlib-1.20.0/configure --target=arm-none-eabi \
      --prefix=$HOME/arm-none-eabi --disable-multilib \
      --disable-newlib-supplied-syscalls
    make all install
A note about the --disable-newlib-supplied-syscalls option:
Disabling the default newlib syscall stub implementation is generally a good idea when you intend to compile for targets without using a linux like operating system, or no OS at all. It will leave you with linker errors on unimplemented stub functions you'll need to provide for newlib.
Removing the option will still enable you to override the newlib provided stubs with your own implementations.

Though, when you plan to use the cross-toolchain in conjunction with CMake, you should omit this option. CMake does some basic tests using the specified compiler definitions (e.g. from a toolchain.cmake file), that'll fail without the default stub implementations supplied.

7. Complete installing GCC


    cd ~/arm-none-eabi-src/build/gcc-4.7.1
    make all install

8. Build GDB


    cd ~/arm-none-eabi-src/build
    mkdir gdb-7.4
    cd gdb-7.4
    ../../src/gdb-7.4/configure --target=arm-none-eabi \
      --prefix=$HOME/arm-none-eabi
    make all install

UPDATE
The same works pretty well for GCC 4.8.2 also.

1 comment:

  1. Thanks for this guide. I'm surprised the openSUSE doesn't have a standard cross-compiler package for ARM, so this is really handy info.

    There is a problem with the following two lines for extra options:

    --enable-cxx-flags='-fno-exceptions \
    -ffunction-sections -fno-omit-frame-pointer'

    I'm using it with gcc 4.8.2 and binutils 2.25. The problem is that when configure runs, it takes those lines literally and dumps them into the makefile. When the makefile runs, it complains "Makefile:116: *** missing separator (did you mean TAB instead of 8 spaces?" The solution is to keep eliminate the continuation line, as follows:

    --enable-cxx-flags='-fno-exceptions -ffunction-sections -fno-omit-frame-pointer'

    ReplyDelete