«

Apr 30 2016

AVR-GCC 6.1.0 and AVR-LIBC 2.0.0 for Windows 32 and 64 bit

This is for those of you who like all the latest shiny things; GCC 6.1.0 was released just a few days ago (at time of writing), along with Binutils 2.26, AVR-LibC 2.0.0 and AVRDUDE 6.3 which were released a few months ago.

The binaries are built from source on an Arch Linux virtual machine with MinGW, apart from AVRDUDE where the pre-built binary was obtained from the official download area. Both 32 bit and 64 bit Windows binaries are provided. There’s probably no benefit from using the 64 bit stuff, but all the cool kids are doing it so why not.
A bash script for building AVR-GCC, AVR-Binutils and AVR-LibC from source is also provided below, making it super easy to build these tools for yourself.

Included tools

Tool Version
GCC 6.1.0
Binutils 2.26
AVR-LibC 2.0.0
AVRDUDE 6.3

Downloads

LATEST
Download
avr-gcc-6.1.0-x64-mingw.zip (48.41 MB)
AVG-GCC 6.1.0 Windows x64 (64 bit)
Downloaded 1105 times
MD5: 5452908FD53FA20FBF42948445969534

LATEST
Download
avr-gcc-6.1.0-x86-mingw.zip (46.25 MB)
AVG-GCC 6.1.0 Windows x86 (32 bit)
Downloaded 728 times
MD5: CDD2323960812E24CC347B3C646EF4D9

I’ve not done too much testing with this, I just know that my AVR projects and various Arduino examples successfully compile and run. However, there is one major bug, see the bugs section at the bottom of this post.
AVR-GCC 6.1.0 seems to produce slightly larger code than 4.7.2 for my N|Watch project, which compiles to 26996 bytes with 4.7.2 and 27368 bytes with 6.1.0.
Arduinos SerialEvent example compiles to 3530 bytes flash usage and 217 bytes RAM usage with the default 4.8.1, while 6.1.0 compiles to 3432 bytes flash and 199 bytes RAM, giving an improvement with both flash and RAM usage.

Upgrading the Arduino IDE

Upgrading the Arduino IDE to AVR-GCC 6.1.0 is pretty easy, though there could be some incompatibilities with certain libraries. I’ve only tested this with 1.6.8.

  1. Download and extract one of the downloads above
  2. Navigate to your Arduino IDE folder
  3. Go to hardware/tools
  4. Move the avr folder somewhere else, like to your desktop (renaming the folder won’t work, Arduino has some auto-detect thing which sometimes gets confused)
  5. Move the extracted folder from earlier to the tools folder and rename it to avr
  6. In the avr folder create a text file called builtin_tools_versions.txt and copy the following into it:
    arduino.avrdude=6.0.1-arduino5
    arduino.avr-gcc=6.1.0-arduino5
    

    The avrdude version needs to stay at 6.0.1, Arduino doesn’t seem to like having the real version (6.3.0) there.

  7. Create a folder called etc
  8. Download this avrdude.conf and place it into the etc folder, Arduino has made a few modifications to the ATtiny85 settings and added an ‘arduinoisp’ programmer
  9. Done! Open up the Arduino IDE, load up the Blink example, upload it to your Arduino and make sure the LED is blinking!

Build script

This build script will install the required packages, create directories and build the tools from source. This should work on Debian 8, Ubuntu 16.04, CentOS 7 and Arch.

#!/bin/bash

# http://www.nongnu.org/avr-libc/user-manual/install_tools.html

# For optimum compile time this should generally be set to the number of CPU cores your machine has
JOBCOUNT=4

# Build Linux toolchain
# A Linux AVR-GCC toolchain is required to build a Windows toolchain
# If the Linux toolchain has already been built then you can set this to 0
BUILD_LINUX=1

# Build 32 bit Windows toolchain
BUILD_WIN32=1

# Build 64 bit Windows toolchain
BUILD_WIN64=1

# Build AVR-LibC
BUILD_LIBC=1

# Output locations for built toolchains
PREFIX_LINUX=/omgwtfbbq/linux
PREFIX_WIN32=/omgwtfbbq/win32
PREFIX_WIN64=/omgwtfbbq/win64
PREFIX_LIBC=/omgwtfbbq/libc

# Install packages
if hash apt-get 2>/dev/null; then
	# This works for Debian 8 and Ubuntu 16.04
	apt-get install wget make mingw-w64 gcc g++ bzip2
elif hash yum 2>/dev/null; then
	# This works for CentOS 7
	yum install wget
	rpm -q epel-release-7-6.noarch >/dev/null
	if [ $? -ne 0 ]; then
		# EPEL is for the MinGW stuff
		rm -f epel-release-7-6.noarch.rpm
		wget https://www.mirrorservice.org/sites/dl.fedoraproject.org/pub/epel//7/x86_64/e/epel-release-7-6.noarch.rpm
		rpm -Uvh epel-release-7-6.noarch.rpm
	fi
	yum install make mingw64-gcc mingw64-gcc-c++ mingw32-gcc mingw32-gcc-c++ gcc gcc-c++ bzip2
elif hash pacman 2>/dev/null; then
	# This works for Arch
	pacman -S --needed wget make mingw-w64-binutils mingw-w64-gcc mingw-w64-crt mingw-w64-headers mingw-w64-winpthreads gcc bzip2
fi

# Stop on errors
set -e

NAME_BINUTILS="binutils-2.26"
NAME_GCC="gcc-6.1.0"
NAME_LIBC="avr-libc-2.0.0"

HOST_WIN32="i686-w64-mingw32"
HOST_WIN64="x86_64-w64-mingw32"

OPTS_BINUTILS="
	--target=avr
	--disable-nls
"

OPTS_GCC="
	--target=avr
	--enable-languages=c,c++
	--disable-nls
	--disable-libssp
	--disable-libada
	--with-dwarf2
	--disable-shared
	--enable-static
"

OPTS_LIBC=""

TIME_START=$(date +%s)

makeDir()
{
	rm -rf "$1/"
	mkdir -p "$1"
}

echo "Clearing output directories..."
[ $BUILD_LINUX -eq 1 ] && makeDir "$PREFIX_LINUX"
[ $BUILD_WIN32 -eq 1 ] && makeDir "$PREFIX_WIN32"
[ $BUILD_WIN64 -eq 1 ] && makeDir "$PREFIX_WIN64"
[ $BUILD_LIBC -eq 1 ] && makeDir "$PREFIX_LIBC"

PATH="$PATH":"$PREFIX_LINUX"/bin
export PATH

CC=""
export CC

echo "Downloading sources..."
rm -f $NAME_BINUTILS.tar.bz2
rm -rf $NAME_BINUTILS/
wget ftp://ftp.mirrorservice.org/sites/ftp.gnu.org/gnu/binutils/$NAME_BINUTILS.tar.bz2
rm -f $NAME_GCC.tar.bz2
rm -rf $NAME_GCC/
wget ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/$NAME_GCC/$NAME_GCC.tar.bz2
if [ $BUILD_LIBC -eq 1 ]; then
	rm -f $NAME_LIBC.tar.bz2
	rm -rf $NAME_LIBC/
	wget ftp://ftp.mirrorservice.org/sites/download.savannah.gnu.org/releases/avr-libc/$NAME_LIBC.tar.bz2
fi

confMake()
{
	../configure --prefix=$1 $2 $3 $4
	make -j $JOBCOUNT
	make install-strip
	rm -rf *
}

# Make AVR-Binutils
echo "Making Binutils..."
echo "Extracting..."
bunzip2 -c $NAME_BINUTILS.tar.bz2 | tar xf -
mkdir -p $NAME_BINUTILS/obj-avr
cd $NAME_BINUTILS/obj-avr
[ $BUILD_LINUX -eq 1 ] && confMake "$PREFIX_LINUX" "$OPTS_BINUTILS"
[ $BUILD_WIN32 -eq 1 ] && confMake "$PREFIX_WIN32" "$OPTS_BINUTILS" --host=$HOST_WIN32 --build=`../config.guess`
[ $BUILD_WIN64 -eq 1 ] && confMake "$PREFIX_WIN64" "$OPTS_BINUTILS" --host=$HOST_WIN64 --build=`../config.guess`
cd ../../

# Make AVR-GCC
echo "Making GCC..."
echo "Extracting..."
bunzip2 -c $NAME_GCC.tar.bz2 | tar xf -
mkdir -p $NAME_GCC/obj-avr
cd $NAME_GCC
./contrib/download_prerequisites
cd obj-avr
[ $BUILD_LINUX -eq 1 ] && confMake "$PREFIX_LINUX" "$OPTS_GCC"
[ $BUILD_WIN32 -eq 1 ] && confMake "$PREFIX_WIN32" "$OPTS_GCC" --host=$HOST_WIN32 --build=`../config.guess`
[ $BUILD_WIN64 -eq 1 ] && confMake "$PREFIX_WIN64" "$OPTS_GCC" --host=$HOST_WIN64 --build=`../config.guess`
cd ../../

# Make AVR-LibC
if [ $BUILD_LIBC -eq 1 ]; then
	echo "Making AVR-LibC..."
	echo "Extracting..."
	bunzip2 -c $NAME_LIBC.tar.bz2 | tar xf -
	mkdir -p $NAME_LIBC/obj-avr
	cd $NAME_LIBC/obj-avr
	confMake "$PREFIX_LIBC" "$OPTS_LIBC" --host=avr --build=`../config.guess`
	cd ../../
fi

TIME_END=$(date +%s)
TIME_RUN=$(($TIME_END - $TIME_START))

echo ""
echo "Done in $TIME_RUN seconds"

exit 0

Building takes about 30 minutes on an Arch Linux virtual machine with 4 cores i5 2500K @ 4GHz and 2GB RAM.

Bugs

There seems to be a bug with 6.1.0 when compiling with -ffunction-sections and any optimization level other than -O0, where strings passed to a function will be stored in flash instead of RAM even though PSTR() hasn’t been used.

	puts("test"); // "test" is incorrectly stored in flash, puts() will attempt to read from RAM!

A work around is to the store the string in a variable then pass that to the function:

	static const char myString[] = "test";
	puts(myString);

*UPDATE*
[More info here]
Another work around would be to add -fno-merge-constants to the compiler options.

18 comments

2 pings

Skip to comment form

  1. Fridolin

    Hi,

    compiling with

    -xc *.c

    results in

    avr-gcc: error: *.c: Invalid argument

    1. Zak Kemble

      Hey Fridolin, I also saw your post on mikrocontroller.net about it being available in previous versions, but none of the GCC versions I tried (4.7.2, 4.9.2, 5.3.0) accept *.c as a valid argument :/

  2. Fridolin

    Please try an official version, for example the one included in Atmel Studio. It works ok with -xc *.c

    -xc *.c is needed to be able to use -flto (which optimizes the code much better than when compiling the files one-by-one).

    1. Fridolin

      This is what an official Atmel Studio

      avr-gcc -v

      outputs (compile parameters). Maybe in your build something is missing?

      Using built-in specs.
      COLLECT_GCC=C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-gcc.exe
      COLLECT_LTO_WRAPPER=c:/program\ files\ (x86)/atmel/atmel\ toolchain/avr8\ gcc/native/3.4.1061/avr8-gnu-toolchain/bin/../
      libexec/gcc/avr/4.8.1/lto-wrapper.exe
      Target: avr
      Configured with: /home/jenkins/workspace/avr8-gnu-toolchain/src/gcc/configure LDFLAGS=-L/home/jenkins/workspace/avr8-gnu
      -toolchain/avr8-gnu-toolchain-win32_x86/lib CPPFLAGS= –target=avr –host=i686-pc-mingw32 –build=x86_64-pc-linux-gnu —
      prefix=/home/jenkins/workspace/avr8-gnu-toolchain/avr8-gnu-toolchain-win32_x86 –libdir=/home/jenkins/workspace/avr8-gnu
      -toolchain/avr8-gnu-toolchain-win32_x86/lib –enable-languages=c,c++ –with-dwarf2 –enable-doc –disable-shared –disab
      le-libada –disable-libssp –disable-nls –with-avrlibc=yes –with-mpfr=/home/jenkins/workspace/avr8-gnu-toolchain/avr8-
      gnu-toolchain-win32_x86 –with-gmp=/home/jenkins/workspace/avr8-gnu-toolchain/avr8-gnu-toolchain-win32_x86 –with-mpc=/h
      ome/jenkins/workspace/avr8-gnu-toolchain/avr8-gnu-toolchain-win32_x86 –enable-win32-registry=avrtoolchain –enable-fixe
      d-point –with-pkgversion=AVR_8_bit_GNU_Toolchain_3.4.5_1522 –with-bugurl=http://www.atmel.com
      Thread model: single
      gcc version 4.8.1 (AVR_8_bit_GNU_Toolchain_3.4.5_1522)

      1. Zak Kemble

        I have that same version of Atmel’s version of GCC, but mine still stays that *.c is invalid. [This] seems to say that you can specify all the files individually, during compile or after once the object files have been created.

      2. Zak Kemble

        Ah my bad, *.c does work, I didn’t have any .c files in the working directory! I’ll post an update in a bit…

      3. Zak Kemble

        Ok, I can’t seem to find anything obvious that I might have missed, so I’m not sure why *.c isn’t working on my 6.1.0 build. I guess a workaround for now would be specify each individual .c file -xc file1.c file2.c file3.c.

        1. Fridolin

          Do you know what’s strange? The order in which I specify all the .c files makes a difference in the binary size (that is also the case in the older versions).

        2. Fridolin

          http://www.mikrocontroller.net/topic/396402?goto=4569504#4569522

          Summary:

          Default configuration of mingw-w64 misses wildcard support.

          Two solutions:

          You can recompile mingw-w64 from source with configure –enable-wildcard

          or

          Use Arch Linux. Their mingw-w64 has wildcard support enabled.

          1. Zak Kemble

            Ah thanks! I’ve rebuilt everything using Arch Linux, *.c now works, the download links have been updated 🙂

  3. Felix

    Have you tried to add “lto” to the list of languages so it reads: c,c++,lto? I read about that in this article: https://www.mikrocontroller.net/articles/AVR-GCC

    1. Zak Kemble

      LTO is enabled by default, so no need for any extra build options.

  4. Kshitij

    Hello Zak,

    This is a commendable effort. However, its missing AVR specific patches. For your next build, would you please apply the binutils-patches for avr and some avr-gcc specific updates, which are available at http://distribute.atmel.no/tools/opensource/Atmel-AVR-GNU-Toolchain// ? Off the top of my head, without the avr-size patch, the avr-size –mcu option will not work. There are also some fixes for ATtiny, iirc. Their GCC fixes do get merged upstream occasionally, but for a custom built toolchain, the binutils fixes do need to be looked into.

    Either way, nice job.

    1. Zak Kemble

      Thanks for the link, though there seems to be a lot of patch failures for the latest GCC and things. I’ll have to go through them sometime, the few I looked at where because they’ve already been merged.

  5. Fridolin

    Hi, have you tried compiling avr-gcc 6.2?

    1. Zak Kemble

      Oh! I didn’t know 6.2 was out, I’ll get it compiled sometime soon.

  6. Stefan

    Where is make.exe?

    1. Zak Kemble

      You can download make [here]. Though, I think I’ll include it with future AVR-GCC builds.

  1. AVR-GCC, Binutils, AVR-LibC, & AVRDUDE in Single Package, for Windows or Linux #Arduino « Adafruit Industries – Makers, hackers, artists, designers and engineers!

    […] tip to Zak Kemble for providing this single-package download for Windows 32/64 and a bash script file for building from source for GCC, Binutils, and […]

  2. AVR TOOLCHAIN based on: gcc 6.20 with libc 2.0.0 & binutils 2.27 » geeks24.eu

    […] the help from: Zak’s Electronics Blog ~* and AVR LIBC user’s manual I have compilied Download from Dropbox: avr-linux-toolchain.tar.gz […]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Are you human? *