Computing stuff tied to the physical world

Setting up a toolchain

In software development, a “toolchain” is a set of tools to generate machine-executable code, i.e. compilers, linkers, and all the other utilities needed to make them work.


On Linux (including Linux running on a VM), there are two pieces to this puzzle:

  • all the standard tools: “make”, “gcc”, and “g++” essentially, and everything they depend on – these are available as a single super-package called “build-essential”
  • the cross-compiler for ARM: on Ubuntu, it’s available as “gcc-arm-none-eabi”

So all you need to do if you’ve been following along and are using Ubuntu 14.04 or later, is:

$ sudo apt-get install build-essential gcc-arm-none-eabi

Don’t include the “$” when typing, that’s the prompt displayed by the shell. In other words, in all these instructions: start typing the text from the point after the “$” prompt.

Hit return to accept the installation suggestions, and let things run for a few moments.

Here are some quick checks to verify that the toolchain has been installed:

$ make -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v [...]
Thread model: posix
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 

$ arm-none-eabi-gcc -v
Using built-in specs.
Target: arm-none-eabi
Configured with: ../gcc-4.8.2/configure [...]
Thread model: single
gcc version 4.8.2 (4.8.2-14ubuntu1+6) 

You’re done. This is all you need to recompile code for the minimal demo and others.

Here is a sample compile session, again with some output truncated for brevity:

$ cd embello/explore/1446-lpc810/minimal
$ make
arm-none-eabi-g++ -mcpu=cortex-m0plus -mthumb [...] -c -o main.o main.cpp
arm-none-eabi-gcc [...] -c -o gcc_startup_lpc8xx.o gcc_startup_lpc8xx.c
arm-none-eabi-gcc -o firmware.elf -Wl,--script=LPC810.ld [...]
arm-none-eabi-objcopy -O binary firmware.elf firmware.bin
lpc21isp -control -bin firmware.bin /dev/ttyUSB* 115200 0
lpc21isp version 1.94
File firmware.bin:
        image size : 396
Image size : 396
Can't open COM-Port /dev/ttyUSB* ! (Error: 2d (0x2))
make: *** [upload] Error 2

That’s two source files compiled, linking everything together into the firmware.elf file, converting that to firmware.bin, and starting the lpc21isp uploader (which then fails because the FTDI converter was not present).

Make is a really nifty little utility: it processes the rules specified in the “Makefile”, doing only as much work as minimally needed. If a source file has not changed since the last time, then make knows that it does not need to run the gcc compiler again.

Here’s the output when calling make a second time:

$ make
lpc21isp -control -bin firmware.bin /dev/ttyUSB* 115200 0
lpc21isp version 1.94

As you can see, only the upload step is performed. In larger projects, “make” can have an immense impact on the speed of development. Just type “make” and it’ll only perform the steps which are needed, based on file modification dates. For example: if the main.o file is newer than the main.cpp source code, then there is no need to compile it again.

(there’s more to it due to include files, but make and gcc can be told to handle all that)


On the Mac, all the standard development tools will have all been installed when you went through the installation of “Homebrew”, as previously described. But it takes slightly more work to install the cross-compiler toolchain for ARM:

  • download the latest official build from this page on
  • be sure to pick the “Mac installation tarball”, not some source code or zip file
  • unpack its contents by double-clicking the downloaded results
  • pick a location to store these files, perhaps “Tools” in your home folder

One last step is to make sure that the system can find these tools from the command line. So if you moved the files to “$HOME/Tools/gcc-arm-none-eabi-4_8-2014q3/”, then you’ll need to add one line to a file called “.bash_profile”, also in your home directory. Enter these three lines, making sure that they match your setup and that there are no typo’s:

echo "PATH=$PATH:$gcc/bin" >> $HOME/.bash_profile

The third line makes sure that the PATH environment also gets extended in all future logins. Be very careful to type “>>” and not “>” or you could wipe out other settings.

Finally, verify that you can indeed launch the compiler from the command line:

$ arm-none-eabi-gcc -v
Using built-in specs.
gcc version 4.8.4 20140725 (release) [...]

That’s it. Compilation for ARM ┬ÁC’s should now work on Mac OS X as well.

Alternative setup – if you already have Arduino IDE version 1.5.x installed, then there is another way to compile for ARM, since that IDE includes a copy of the ARM gcc toolchain. Exact details will depend on the IDE version, but something like this should do the trick:

echo "PATH=$PATH:$gcc/bin" >> $HOME/.bash_profile

Having said that, it’s easy to use the toolchain from a VM on the Mac, so examples from now on will use Linux. This way, everything works the same on Linux, Windows, and Mac!

[Back to article index]