Skip to content

Instantly share code, notes, and snippets.

@itspngu
Last active December 28, 2020 21:40
Show Gist options
  • Save itspngu/3e4e786f6533b752b903027b55064ee4 to your computer and use it in GitHub Desktop.
Save itspngu/3e4e786f6533b752b903027b55064ee4 to your computer and use it in GitHub Desktop.

Installing an up-to-date AVR cross compilation toolchain for QMK on Ubuntu 20.04+

Unfortunately Ubuntu packages a fairly old (5.3.0) version of gcc-avr at the time of writing. Versions of gcc-avr from 8.3.0 onwards will produce significantly smaller binaries. The steps of building and installing a cutting-edge AVR toolchain on Ubuntu (tested on 20.04/WSL2 and 20.10/Baremetal) are outlined below.

Most of the procedure is loosely based on this manpage.

Prequisites

It's a good idea to run all of this from a folder dedicated to it.

$ mkdir -p avr_toolchain && cd avr_toolchain

Your life will be easier if you separate these tools from the rest of your stuff, else it'll bite you back at random, unless your system is dedicated to cross-compiling for AVR.

Feel free to choose a different path for this, as long as you keep it consistent while executing the build & installation process.

$ PREFIX=/usr/local/avr
$ export PREFIX
$ sudo mkdir -p $PREFIX
$ sudo chown -R "$(id -u):$(id -g)" $PREFIX

You'll want to prepend this directory to your PATH so it overrides whatever else you might already have lurking in your system.

$ PATH=$PREFIX/bin:$PATH
$ export PATH

Mind you that export statements are temporary, so once you quit the current shell session you'll have to set them again or you'll end up looking at confusing error messages (or worse).

Installation

Acquire the sources for appropriate releases of GNU binutils, gcc and avr-libc. The full lists of releases can be found at:

Different release versions might not always be compatible with each other. This procedure has been tested using the archives shown below. If one of them is unavailable, too slow, or otherwise broken, look for a mirror at the links listed above.

$ wget -qO- http://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.gz | tar xzvf -
$ wget -qO- https://ftp.mpi-inf.mpg.de/pub/gnu/mirror/gcc.gnu.org/pub/gcc/releases/gcc-10.2.0/gcc-10.2.0.tar.gz | tar xzvf -
$ wget -qO- http://download.savannah.gnu.org/releases/avr-libc/avr-libc-2.0.0.tar.bz2 | tar xjvf -

Before continuing, you'll need a working host toolchain (i.e. the appropriate tools to build software for the system you're using right now). This includes GNU make, a compiler (preferably GCC), a linker, etc. Google is your friend. If I recall correctly, something along the lines of apt install build-essential should get you most, if not all of the way there on Debian based distros. If you're not sure what you have or need, just continue with the process and work your way through error messages complaining about missing files until you're there.

If you're not in a hurry, it might make sense to check out the configure scripts for each of these to see what they do and if things could perhaps be en- or disabled to better suit your use case. You can also pass optimizing compiler and linker flags to the make invocation in each of these steps, but your mileage may vary; if all you do is compile firmware for keyboards occasionally (a comparatively trivial task) you'd unlikely gain non-negligible benefits from that, at the expense of making the toolchain build process (what you're working through right now) take quite a bit longer.

binutils

Start out by building and installing GNU binutils. It's recommended to create an output directory to not pollute the source files with build artifacts.

$ cd binutils-2.35
$ mkdir -p obj-avr && cd obj-avr
$ ../configure --prefix=$PREFIX --target=avr --disable-nls

If that worked, you can build and install it:

$ make -j$(nproc)
$ make install

Take note of how you don't need to sudo the make install command because you're installing into a non-system directory.

gcc

On to gcc. You'll need to fetch some prequisite packages. The GNU folks graciously provide a script to make this easy.

$ cd gcc-10.2.0
$ ./contrib/download_prerequisites

Same as above, work from a subdirectory. Compilation will take a while, so grab a cup of your favourite beverage while it's running. The following steps have only been tested with coffee and are not guaranteed to work with anything else.

$ mkdir -p obj-avr && cd obj-avr
$ ../configure --prefix=$PREFIX --target=avr --enable-languages=c,c++,lto --disable-nls --disable-libssp --with-dwarf2
$ make -j$(nproc)
$ make install

avr-libc

Compiling this with debug symbols enabled is optional but recommended.

$ cd avr-libc-2.0.0
$ mkdir -p obj-avr && cd obj-avr
$ ../configure --prefix=$PREFIX --build=`../config.guess` --host=avr --enable-debug-info=dwarf-2
$ make -j$(nproc)
$ make install

Wrapping up

If the above completed successfully, which avr-gcc should return the path you specified as PREFIX and avr-gcc -v should return the version of gcc you opted for.

Try compiling firmware for a board to make sure everything works. After that, you can permanently add the installation directory to your PATH or assign it to QMK make by prepending it to the command through other means (e.g. PATH=/usr/local/avr/bin:$PATH LD_LIBRARY_PATH=/usr/local/avr/lib:$LD_LIBRARY_PATH make keyboard:keymap from the command line or a wrapping shell script).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment