Silmor . de
Site Links:
Impressum / Publisher

Electronics: Compiling AVR-GCC

The Atmel (now owned by Microchip) AVR microcontrollers are very popular among hobbyists and professionals alike. One of the nice things about them is that there is a completely Free / Open Source tool chain based on GCC, a lot of relatively affordable hardware utilities and a lot of knowledge resources out there.

There are a couple of "official" versions of GCC for AVR - one from Atmel/Microchip, at least one from the Arduino project and a few contained in various Linux distributions. The commonality between all of them is that they tend to be trailing the GCC for PC development a bit. Or to put it more blunt: those packages are effin' ancient! Especially for users of C++ this can be quite frustrating, considering that GCC officially supports the AVR platform and newer versions of the C++ language have some really useful features that also help with embedded platforms.

This article gives an overview on how you can compile the newest stable tool chain for yourself. It describes this process for a Linux host - users of Windows or MacOS will have to modify some parts of the recipe given here (sorry, I never tried this on those systems, so I cannot help). It assumes that you are comfortable with compiling your own GCC - if not please read up on how to do this (there are plenty of tutorials out there) and try for a normal host GCC first (one that generates binaries for your normal Operating System, not a cross-compiler).

Getting the Sources

There are four components that you need for your completely Free / Open Source tool chain:

You need GIT to clone the repositories. You could simply download release packages, but using GIT is in my opinion more convenient, since it allows you to upgrade more easily when a new version of any of those tools is released.

Tool GIT URL Homepage
AVRdude https://github.com/avrdudes/avrdude.git https://github.com/avrdudes/avrdude
AVR-libc https://github.com/avrdudes/avr-libc.git https://github.com/avrdudes/avr-libc
GCC git://gcc.gnu.org/git/gcc.git https://www.gnu.org/software/gcc/
Binutils git://sourceware.org/git/binutils-gdb.git https://www.gnu.org/software/binutils/

Step 1: git clone the four repositories listed above into a fresh directory.

Step 2: in each one of them list the tags (git tag) and chose the latest release per git checkout. Per default Git will check out the master/main branch, but that is not as stable as we need for normal work.

I tend to create local branches for those checkouts, e.g. git checkout -b local-12.3 releases/gcc-12.3.0 - this way I know which ones I have compiled for myself before and can easily go back and recompile if necessary. It also allows me to apply patches for bugs if necessary without losing track during the next time I upgrade.

Compiling and Installing

Those tools need to be compiled in a specific order, since they rely on each other:

  1. Binutils is pretty independent from all other tools, since it exclusively deals with binaries
  2. GCC relies on Binutils to handle the compiled output and to do the linking, so Binutils needs to be installed when GCC compiles
  3. AVR-libc relies on GCC to compile, so GCC needs to be installed first
  4. AVRdude is independent again and can be compiled before or after all the others

Most of these packages can be built out-of-tree, which is highly recommended to keep the source tree clean.

You need to chose a target directory to install into. I myself usually create a fresh one for each build and then link it from a central place that I put into my $PATH variable when needed.

Compiling Binutils

Binutils can be built out of tree. Simply create an empty directory and then execute the usual sequence of commands:

../binutils-gdb/configure --prefix=$HOME/avrtools --disable-nls --target=avr
make -j2
make install

The configure script might complain that it needs some basic libraries like zlib or some more complex stuff like the libgmp/libmpfr multi-precision libraries. It will tell you exactly what it is missing.

The --target=avr switch selects the AVR platform for the utils and GDB.

The --disable-nls switch disables localized error messages and with this eliminates some dependencies.

The -j2 parameter to make tells Make to parallelize the build process - for maximum speed set it to the number CPU cores you have in the host PC.

The --prefix=$HOME/avrtools installs the binaries into the avrtools sub-directory in the home directory of the user. You can swap it for whatever directory you like, but it has to be the same for all four packages.

Compiling GCC

The recipe for GCC is quite similar:

../gcc/configure --prefix=$HOME/avrtools --disable-nls --enable-languages=c,c++ --target=avr --disable-libssp --with-dwarf2
nice make -j2
make install

The --enable-languages switch selects the programming languages that are supported by the compiler. I only use C and C++, so there is no need to select other languages like Fortran, Objective-C etc.

SSP is the stack protector library, which is not very useful on a microcontroller. The DWARF-2 format is the preferred one for AVR binaries before they get translated to the actual target format for the programmer hardware.

The GCC configure may complain about more missing libraries. In order to work properly the compile process expects Binutils to already be installed at the target prefix.

AVR LibC

AVR-LibC does not support out-of-tree builds. A nice trick is to create a copy of the source tree before you build - this way your source directory remains unaffected by the build process.

The recipe then looks like this:

#create out-of-tree copy
cd avr-libc
git checkout-index -af --prefix=$(pwd)/../build-libc/
cd ../build-libc

#prepare:
./bootstrap

#build:
./configure --prefix=$HOME/avrtools --build=`./config.guess` --host=avr --enable-debug-info=dwarf-4
nice make -j2
make install

The --build=... parameter sets the system you are working on, i.e. the host - it is usually safe to let it guess on its own.

The --host=avr parameter forces the target system (not the host) to be AVR.

The --enable-debug-info=... parameter makes sure there is something for GDB in case you need to debug your microcontroller. It does not negatively affect the target binaries, since debug info is stripped out before the binaries are uploaded to the microcontroller.

AVRdude

AVRdude needs to access the programmer hardware. For this is has dependencies on libUSB and HIDAPI. CMake will tell you if something important is missing.

AVRdude has been converted to CMake around version 7, so the recipe looks somewhat different:

cmake -D CMAKE_BUILD_TYPE=RelWithDebInfo -B build_linux -D CMAKE_INSTALL_PREFIX=$HOME/avrtools ../avrdude
cmake --build build_linux
cmake --build build_linux --target install

The -D CMAKE_BUILD_TYPE=RelWithDebInfo parameter tells CMake to create a release build with added debug info - I do this to be able to debug AVRdude itself. Usually this would not be needed and you can substitute Release instead.

The --build ... parameter directs CMake to run the actual build. While --build ... --target install installs the completed program.


Webmaster: webmaster AT silmor DOT de