avr-gcc 4.7.0 and avr-libc 1.8.0 compiled for Windows

At the time of writing, April 2012, the gcc team have released version 4.7.0 of the compiler package and the avr-libc developers have also released version 1.8.0 of the avr-libc library.

Version list

Tool Version Configuration
avr-gcc 4.7.0 –with-gmp=/usr/local –with-mpfr=/usr/local –with-mpc=/usr/local –prefix=/c/avrgcc –target=avr –enable-languages=c,c++ –with-dwarf2 –enable-doc –disable-shared –disable-libada –disable-libssp
avr-libc 1.8.0 –host=avr –prefix=/c/avrgcc –enable-doc –disable-versioned-doc –enable-html-doc –enable-man-doc –mandir=/c/avrgcc/share/man –datadir=/c/avrgcc –build=i686-pc-mingw32 build_alias=i686-pc-mingw32
avrdude 5.1.1 –prefix=/c/avrgcc –datadir=/c/avrgcc –sysconfdir=/c/avrgcc/bin –enable-doc –disable-versioned-doc

Update 24 Feb 2013: now includes libusb support.

Built from source

Both of these packages are open-source and are available to download and build from their official repositories. For me with my Linux development hat on that’s a relatively easy task but swapping hats for my Windows developer attire I have to set up a rather specialised toolchain that can emulate enough of a Unix-like system to build the source packages and particularly the documentation.

Well I’ve done all that for you and now you can download and extract a single zip file that will give you the whole lot, ready to run. The binaries were built under the msys environment which means they have no external dependencies and will just run as-is.

Important bug fixes

The most important bug fix that I can see concerns Arduino Mega users. Earlier versions of avr-libc contained buggy code for global constructor initialisation. If your program is larger than 64Kb and the linker locates a class constructor in the upper 64Kb and you instantiate that class at global scope then your program will crash on startup. The bug fix seems to also include the problem where register r20 would be corrupted during the constructor call. This is good.

On a less important note the annoying and wrong warning only initialized variables can be placed into program memory area is removed. Thank goodness for that!

Integrated with the Arduino IDE

Furthermore, I’ve done the necessary hackery to integrate these new tools into the Arduino IDE so that IDE users can benefit from the improvements and bug fixes offered in the new releases.

So without further ado, let’s get on with the instructions.

Download it

Click here to go to my downloads page and get the 77Mb zip package.

Extract it to your hard disk

I recommend extracting to your root directory (C:/). This will result in an avrgcc directory being created with everything in it.

If you don’t have administrator access to your PC then you can install to another location. However, do not install to a directory that has spaces in it such as c:\Program Files or the Windows XP home directory root (c:\Documents and Settings\username). The Windows Vista and Windows 7 home directory (c:\Users\username) root is safe however.

Referencing the compiler

If you want to compile from the command line then you can update your PATH variable to the avrgcc/bin directory, for example under Cygwin I can do this:


Updating the cygwin PATH variable

If you’re a Makefile person then no doubt you have variables set to where your compiler, its includes and its libraries are located. Just update those and you’re off.

Upgrading Arduino IDE 1.0

Note: This is an advanced option that may have side effects that have not yet been discovered. The official status is “works for me”. You may find issues that I have not come across yet.

The procedure is quite straightforward, surprisingly so given that the compiler and library shipped with the IDE is ancient (gcc 4.3.3). Nevertheless upgrading the IDE should be considered an advanced option that you probably don’t want to do unless you are having issues with it that you believe the upgrade will solve.

Step 1: Backup the old tools

Navigate to hardware/tools subdirectory of the Arduino installation and make a copy of the avr subdirectory like this.


Make a backup

Step 2: Drag and drop the new tools

  1. Navigate into the c:\avrgcc directory and select everything in it.
  2. Navigate a new window to the arduino-1.0\hardware\tools\avr subdirectory.
  3. Drag and drop the entire contents of the avrgcc directory as a copy (not a move!) into the arduino directory. Say yes to all prompts from Windows about merges and overwrites.

Step 3: Backup the Arduino library

Navigate to the hardware\arduino\cores subdirectory of your arduino installation and make a copy of the arduino subdirectory.

Step 4: Fix problems in the Arduino library

The final step is to fix up some problems with the Arduino library. Some are due to the library being written for the old avr-libc and others are just sloppy coding that we need to clean up.

Navigate into the hardware\arduino\cores\arduino directory that we just backed up and download and overwrite the files therein with those in the following table.

File Reason for fix
HardwareSerial.cpp The USART macros have changed and old macros deprecated. Rather than rewrite HardwareSerial.cpp we enable support for the old macros with the __AVR_LIBC_DEPRECATED_ENABLE__ preprocessor symbol.
IPAddress.cpp
and IPAddress.h
Poor code quality here. The 4-octet class member is forcibly type-punned to an incompatible type in several places. This hack forces gcc to disable an entire class of optimisations. The new compiler automatically enables strict-aliasing when size optimisations are selected so we get told about this. The fix is to declare the 4-octet member as a union so it can be used in a type-safe manner.
Print.cpp The old prog_char et al. typedefs are no longer supported. The correct way to declare something to be in flash is with __attribute__((progmem)) on the variable name, not the type. There is one place in Print.cpp where I had to do this.
WString.h The F(string_literal) macro is incorrectly declared. reinterpret_cast can never cast away cv-qualifiers as it is being asked to do in this file. The fix is to keep the const qualifier in the cast target.

Done!

That’s it. You should now be able to launch the IDE and compile using the new compiler.

  • Thanks for building this – it seems to work great!

    I did notice one issue: It seems that the WinAVR version of binutils (specifically avr-size) has a patch to support the -C and -mmcu flags that your built version doesn't. This causes an error when trying to see how much of the device space is used (for instance, in conjunction with http://www.arduinodev.com/codeblocks/ ) To work around this for now, I just used the old avr-size binary instead of the new one.

    It looks like the Debian package for "binutils-avr" is more or less the canonical source for the modified binutils, if you want an "upstream" to build from. http://packages.debian.org/changelogs/pool/main/b

    On a completely different note: Have you submitted the changes to the Arduino core libraries upstream? They've got it up on Github which should make this fairly easy: https://github.com/arduino/Arduino

    Thanks again for building this!

    • Good point regarding the avr additions to the standard binutils. Debian is my preferred Linux distro so I'll pull the source and do a Windows build. The additional utilities would come in handy.

      At least one of the changes I made already exists in the Arduino github. I may submit the others, there's no reason not to I guess.

  • Pete Skeggs

    Thanks for doing this. I started the task of getting avr-libc 1.8.0 to build under Windows for use with Arduino 1.0.1, and ran into too many issues.

    Are the changes you made to hardware/arduino/cores/arduino compatible with Arduino 1.0.1? It seems from step 3 you were using 1.0.

  • Pete Skeggs

    I gave it a try, but this does not seem to work with Arduino 1.0.1, even after merging your changes to the hardware/arduino/cores/arduino files. One problem is that the improvements you made to IPAddress need to be integrated into libraries/Ethernet/w5100.*. Even reverting that, I get a "collect2.exe error: ld returned 5" error. The verbose build output in the Arduino IDE doesn't give any clue about what is causing the ld error.

    • Scott

      Hi Andy, I think I have some more of the error Pete is talking about:
      From: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=

      With your patches, trying to compile the "WebClient" example

      /usr/share/arduino/libraries/Ethernet/Ethernet.cpp: In member function
      ‘void EthernetClass::begin(uint8_t*, IPAddress, IPAddress, IPAddress,
      IPAddress)’:
      /usr/share/arduino/libraries/Ethernet/Ethernet.cpp:64:39: error: no
      matching function for call to
      ‘W5100Class::setIPAddress(IPAddress::<anonymous union>&)’
      /usr/share/arduino/libraries/Ethernet/Ethernet.cpp:64:39: note:
      candidate is:
      In file included from
      /usr/share/arduino/libraries/Ethernet/Ethernet.cpp:1:0:
      /usr/share/arduino/libraries/Ethernet/utility/w5100.h:392:6: note: void
      W5100Class::setIPAddress(uint8_t*)
      /usr/share/arduino/libraries/Ethernet/utility/w5100.h:392:6: note: no
      known conversion for argument 1 from ‘IPAddress::<anonymous union>’ to
      ‘uint8_t* {aka unsigned char*}’

      • I have Arduino 1.0.1 so I'll follow up on these. I'm a bit pressed with finishing a new article but should get to it soon.

        • Scott

          I think I fixed it, but can't test it – it's possibly an easy fix (see below)

          Index: arduino/libraries/Ethernet/Ethernet.cpp
          ===================================================================
          — arduino.orig/libraries/Ethernet/Ethernet.cpp2012-03-11 19:09:34.421223498 -0400
          +++ arduino/libraries/Ethernet/Ethernet.cpp2012-08-17 12:14:09.845198234 -0400
          @@ -61,9 +61,9 @@
          {
          W5100.init();
          W5100.setMACAddress(mac);
          – W5100.setIPAddress(local_ip._address);
          – W5100.setGatewayIp(gateway._address);
          – W5100.setSubnetMask(subnet._address);
          + W5100.setIPAddress(local_ip._address.a8);
          + W5100.setGatewayIp(gateway._address.a8);
          + W5100.setSubnetMask(subnet._address.a8);
          _dnsServerAddress = dns_server;
          }

          • Scott

            The above fix works for uno boards, but when you choose the Mega 2560/ADK board and try to compile the ethenet library, you get:

            collect2: error: ld terminated with signal 11 [Segmentation fault]

            As a work around, do you know of a compiler optimization we may turn off to get it to compile (perhaps? I really am not sure about this)

          • Scott

            Some more info:
            The ld crash using a mega is related, I believe to the fact that the megas use the -Wl,–relax linker command in Compiler.java.

            There is possibly a bug in ld (that was already patched but needs to possible be fixed), which can be seen here: http://sourceware.org/bugzilla/show_bug.cgi?id=13…. So the bug may not be with any of the changes from this blog, but probably a bug in avr binutils.

          • Pavel

            Did anybody overcome the ld crash? I'm stuck trying to get it work.

            Thanks a lot! I'll appreciate any help!

            // Arduino Mega / Ethernet shield (but crashes on any sample, actually).

  • Scott

    Ok, so the above bug was fixed with the above patch, but a new one showed up:
    dns.getHostByName(server, out_ip);
    is apparently not working.
    See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=

  • James Brown

    After replacing the AVR directory of a newly installed Arduino 1.0.2, I get the following error:

    avrdude: error: no usb support. Please compile again with libusb installed.
    avrdude: programmer operation not supported

    I was not getting this error prior to installing the new avr-gcc 4.7 stuff. Seems like maybe the avrdude was built without USB support which is a major issue for those using USB programmers like the usbtiny.

    – James

    • Hi James, you're right. I'll see if I can configure and build in USB support. In the meantime you can fall back to the previous version of avrdude as it is not dependent on the version of the rest of toolchain.

      • Isaac

        Hi Andy! Thanks for this blog. I would like to know what happened about this USB support error, have you fixed it?

        • I'm pleased to announce that avrdude-5.11 has been recompiled with libusb support. You can either download the full package again (62Mb) or just download the recompiled avrdude.exe and overwrite your previous file. Here's the link to just the fixed avrdude.exe:

          http://andybrown.me.uk/files/avrdude-5.11.zip

          Before the recompile:

          $. ls -l avrdude.exe
          -rwxr-xr-x 1 andy Administrators 299520 Feb 24 11:46 avrdude.exe
          $. avrdude -c usbasp -p m8
          avrdude.exe: error: no usb support. please compile again with libusb installed.
          avrdude.exe: programmer operation not supported

          avrdude.exe done. Thank you.

          After the recompile:

          $. avrdude -c usbasp -p m8
          avrdude.exe: error: could not find USB device "USBasp" with vid=0x16c0 pid=0x5dc

          avrdude.exe done. Thank you.

          $. md5sum.exe avrdude.exe
          3d3ba1b63e37db155e034f27139bade5 *avrdude.exe

  • colinirwin

    I've posted a further step-by-step guide on my site – at: http://aethersdr.org/blogs/colin/arduino_with_upd… – given some small differences in my setup.

    These were:
    – use of Eclipse; and
    – file updates made with the Arduino 1.0.3 software.

    A quick question: Do I assume correctly that all the headers, etc., can be used from the gcc 4.3.3 release? These are not included in the archive available on the download page.

    • Hi Colin,

      Which headers are we referring to? Those relevant to avr-libc are in avrgcc/avr/include. All the others that I can think of, e.g. libstdc++ , are for PC's etc and could not be used on the Arduino.

      – Andy

      • colinirwin

        Hi Andy,
        Of course you're right – I was looking in the wrong place. All the header files are indeed in the avrgcc/avr/include directory.
        I changed the Eclipse AVR directory, rebuilt everything and all is OK. I'll update my blog posting to reflect this addition
        Thanks!

        Colin

    • colinirwin

      I've updated the posting at http://aethersdr.org/blogs/colin/arduino_with_upd… to include the addition in Eclipse of the include directory for the AVR platform.

  • mpflaga

    looks like 1.0.3's HardwareSerial.cpp versus its HardwareSerial.h has significantly changed from when you used IDE 1.0. I have had to revert back to 1.0.3's original. This may be the case for 1.0.1 and 1.0.2. I am not sure but I think the only function difference is your add of the __AVR_LIBC_DEPRECATED_ENABLE__.

    I also find that 1.0.3 WString.h equal yours.

    I can confirm the like can be successfully done to IDE 1.5.2(beta) as it appears to be use the same core libraries as IDE 1.0.3.

    • Cheers for the heads-up on this. I'll take a look at 1.0.3 later this week to see what they've fixed/improved.

  • Hey, thanks for this, it's really convenient!

    I did the same to build avr-gcc 4.7.2 on Mac OS, there's a tutorial here: http://fortyseveneffects.com/building-avr-gcc-for

    I had to tweak avr-size to include the -C option (very useful to show a nice report of memory usage), as described here: http://asf.atmel.com/bugzilla/show_bug.cgi?id=135

    I'll try and do the same as you did to have this patch as well (maybe getting the 4.7.2 update along the way).

    Cheers!

  • Pingback: DCF77 vs. GPS | Blinkenlight()

  • ZT

    I’ve the same problem on Arduino Ide 1.0.6. When I compile everithing selecting mega2560, ld.exe crash.