Building avr-gcc for C++11 on Mac OS

Yesterday I saw that the support of C++11 has been added in GCC 4.7. Since avr-gcc is just a special configuration of gcc itself, it is then possible to build AVR programs using C++11. Of course, the standard library will not be available, but the language itself has some interesting features.

Since I don’t have the latest avr-gcc on Mac OS, I confirmed the theory by building a test program on the Raspberry Pi (equipped with avr-gcc 4.7.0). Yup, it works.

The latest available version of avr-gcc on Mac OS 10.6 is either 4.5.1 (using CrossPack) or 4.7.0 (using MacPorts). I could use MacPorts, but I don’t like the fact they install everything into /opt/local, it doubles up with the /usr/local directory where I usually install cross-compilers etc. If you want the easy version, go for the MacPorts solution. Otherwise, read on and hold tight..

Building the AVR toolchain from scratch on Mac OS

The complete toolchain is composed of three parts:

  • The compilers (avr-gcc, avr-c++ etc)
  • The binutils (avr-size, avr-objcopy etc)
  • The C library (avr-libc containing all the includes and precompiled libraries

The installation process in described on the avr-libc webpage.

Prerequisites

I’m assuming you have the following tools installed on your machine:

  • Xcode development tools (my version is 3.2.6)
  • MacPorts (to fetch the libraries we need to build gcc)

Getting the sources

The gcc sources are hosted on FTP servers, which can be quite slow. I used SVN instead, with the following command:

svn co svn://gcc.gnu.org/svn/gcc/tags/gcc_4_7_2_release

The sources for the binutils can be found here, and the sources for the avr-libc can be found here.

Building the binutils

Before building the binutils, you will need to apply a patch to add AVR support to the avr-size tool. Here is the patch released by Atmel, however it failed to build on my machine, and I had to apply another one.

Requirements for the compilers

To build gcc, you will need the following libraries (for floating-point math):

  • gmp
  • mpfr
  • libmpc (be carefull not to install mpc like I did, it’s not the same thing)

That can be done with the following command:

sudo port install gmp mpfr libmpc

You will also need the iconv library, but the MacPorts version did not seem to work, so you’ll have to build it manually, from the sources. You will also need to copy this patch file to the libiconv-1.14 directory (or whatever version you download).

cd libiconv-1.14
mkdir build && cd build
../configure --prefix=/usr/local/temp/iconv
cd ..
patch --input libiconv_patch_gcc_4.7.2.txt
# when prompted for file to patch, enter build/include/iconv.h
cd build
make
make install

Here I install it into a temporary directory, since I might not need it later.

Building the compilers

To build GCC, we need to tell it where to look for the gmp, mpfr, mpc and iconv libraries. Make sure you don’t have the iconv library installed with MacPorts, as it will override the one you just built in /usr/local/temp/iconv.

cd gcc_4_7_2_release/
mkdir obj-avr && cd obj-avr
../configure --prefix=/usr/local/avr --target=avr --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2 --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-libiconv-prefix=/usr/local/temp/iconv
make
make install

Building the C library

If you had an older version of avr-gcc installed, now might be the time to remove it (or at least to remove its path from $PATH), so you can build the avr-libc using your shiny new compiler.

This step is quite straightforward, just follow the instructions and you should be fine.

Building a test program

In order to enable C++11 features, you’ll have to pass the following flag to the compiler:

-std=c++11
Now try the following program, demoing the auto variables and range-based for loop:
int main()
{
    const char foo[] = "Hello, World!";
    char bar[14] = { 0 };
    auto i = 0;

    for (auto baz: foo)
    {
         bar[i++] = baz;
    }
    return 0;
}

You will notice that we’re returning from main, although it’s considered to be a blasphemy by some embedded developers, what it will do is only continuing executing empty instructions until looping back to the reset point. Anyway, this would not be worth much uploading onto a chip, since there would be no way to check that bar contains “Hello, World!” after execution..

  • http://i.got.nothing.to/blog Guyzmo

    Or a simpler method would be to just use homebrew:

    brew tap larsimmisch/avr
    brew install avr-gcc

    and voila, you’ve got avr-gcc 4.7 :-)

    • Francois

      Great, thanks for the tip!