The GCC toolchain is a nice way to get started with bare-metal ARM platforms because it is free, well-supported, and something that many C programmers are already familiar with. It is also constantly improving, and while most Linux distributions include a version of the
arm-none-eabi GCC toolchain in their default package managers, those versions are sometimes old enough that I run into bugs with things like multilib/multiarch support.
So after trying and failing a few times to build and install this toolchain, I thought I would share what eventually worked for me. If you are building this on a system without much free disk space, this did take about 16GB of disk space when I ran it – but you shouldn’t need to keep more than ~500MB of that. I ended up building it on an ext3-formatted 32GB USB drive, and that seemed to work fine. You will probably run into errors if you try to run this on a FAT-formatted drive like a new USB stick, though, because the build process will run
chmod and that will fail on a filesystem that doesn’t support file permissions. You might be able to make it work with an NTFS drive, but I digress.
Anyways, the first step is downloading the code, so let’s get started!
Step 1: Download the Source Code
The first step is to download the
arm-none-eabi-gcc source code from ARM’s website – you want the “Source Invariant” version. If you are using a common architecture such as
x86_64, you can also download a pre-built version of the latest release, but you probably want to build the thing yourself if you are reading this guide. If you want to make sure that the file you downloaded was not corrupted or tampered with, you can check it against the MD5 checksum listed under the file’s name on the download page:
> md5sum gcc-arm-none-eabi-8-2018-q4-major-src.tar.bz2 d6071d95064819d546fe06c49fb9d481 gcc-arm-none-eabi-8-2018-q4-major-src.tar.bz2
That looks like it matches as of the time of writing. The archive contains build scripts and code for the whole toolchain, so create a new directory to build the toolchain in – I’ll use
~/arm_gcc/ as an example. Once it finishes downloading, move the archive to that folder and extract it:
> mkdir ~/arm_gcc > cd ~/arm_gcc > mv [Your_Downloads_Folder]/gcc-arm-none-eabi-8-2018-q4-major-src.tar.bz2 . > tar -xvf gcc-arm-none-eabi-8-2018-q4-major-src.tar.bz2
The file that I downloaded was called
gcc-arm-none-eabi-8-2018-q4-major-src.tar.bz2, but yours will depend on where you are in time. The extracted archive will make a new directory with a similar name – take a look inside, and you’ll see a few scripts and a ‘how-to’ document alongside the source code:
> cd gcc-arm-none-eabi-8-2018-q4-major/ > ls build-common.sh build-toolchain.sh install-sources.sh python-config.sh release.txt build-prerequisites.sh How-to-build-toolchain.pdf license.txt readme.txt src
Step 2: Build the Toolchain
How-to-build-toolchain.pdf file contains instructions for setting up and running the build – it’s almost as simple as installing the prerequisites and running a few scripts in sequence, but there are a few things worth calling out. First, read the ‘how-to-build’ document. It’s short, and if you read it you won’t go looking for a Makefile in the
src/ directory like I did.
The prerequisites are easy to install; if you are using a Debian-based Linux distribution like Ubuntu, this command should work with the version of GCC that I wrote this guide for (don’t forget to use
sudo or be root):
apt-get update apt-get install build-essential autoconf autogen bison dejagnu flex flip gawk git gperf gzip nsis openssh-client p7zip-full perl python-dev libisl-dev scons tcl texinfo tofrodos wget zip texlive texlive-extra-utils libncurses5-dev
If you are building a newer version of the toolchain than the “2018-Q4” release, double-check the ‘how to build’ document to make sure those are the only dependencies that you need. And some of these packages might be fairly large, but I think you can probably omit the
texlive packages if you tell the build system to skip creating manuals and documentation in the final step (mentioned below).
Once the dependencies are installed, proceed to step 1.3 in the ‘how-to-build’ document (titled, “Build GNU Tools for Arm Embedded Processors”). Note that I haven’t built the toolchain on Mac OSX, and it looks like there are some extra steps for that environment.
The first step after un-zipping the source files is to run the
install-sources.sh script, which extracts the source code for each part of the toolchain. It also downloads some supporting libraries, so you’ll need internet access for this step as well as the previous one:
--skip_steps=mingw32 option tells the build system not to create a Windows-compatible toolchain. Since I only plan to run this on the Linux host it was built on, this option saves time and space. If you do need to build a Windows toolchain, I guess you can skip the ‘skip_steps’ step for all of these scripts.
Once the sources are extracted (the larger archives might take a little while to unpack), you can set up the build system and supporting libraries with:
This step will also take a little while as it runs through a ‘configure/make’ cycle for each dependency that it needs to build. Once it is done, you can build the toolchain itself. And while I haven’t tried this, it looks like you can skip building the manuals and documentation if you didn’t want to install the large
texlive packages by passing in
This will take even longer than the previous step – it can easily run for several hours (or even longer on a slow machine,) and in my case the terminal output froze towards the end of the process; I had to guess when it finished by checking that there were no more compiler/linker/etc processes running and that the size of the build folder stopped changing.
When the build does finish, you should find a directory called
install-native/ in the same directory that you ran the build scripts in. That folder will contain the finished toolchain which we will install in the next step.
And if you want to backup the toolchain so you don’t need to re-build it later, there should also be a directory called
pkg/ which contains two tarballs. One contains the same final build as the
install-native/ directory, and the other contains the toolchain’s source code as it was generated for your platform.
Step 3: Install the Toolchain
It looks like the toolchain’s build contains four directories:
arm-none-eabi/. I’m not sure why it creates the extra
arm-none-eabi/ directory, and you might be able to adjust this by using common command-line options like
--prefix during the build stage, but I didn’t look into that too much. It might bother you if you really like having a clean filesystem though, because the process I used to install the toolchain is embarrassingly simple – just copy everything into the
cp -R install-native/* /usr/ sudo ldconfig
You can check that the program was installed and view some basic information about its path settings with basic diagnostic commands like
which arm-none-eabi-gcc and
To uninstall the toolchain, you should be able to just remove the directories which you copied – in my case those were:
/usr/bin/arm-none-eabi-* /usr/arm-none-eabi/ /usr/lib/gcc/arm-none-eabi/ /usr/share/gcc-arm-none-eabi/ /usr/share/doc/gcc-arm-none-eabi/
I also ended up with a few
libcc1.so files under the
lib/ directory, but that looks like an already-reported bug. It may cause conflicts with
avr-gcc, but I’m one of those people who can’t see any point to using an AVR core these days; it seems like you pay more for less when there are options like
PICs on the cheap/low-power/simple end and
Cortex-M0s on the cheap/high-power end.
That should be all there is to it – after running
ldconfig, you should be able to use the arm-none-eabi toolchain normally. In my case, building and installing an up-to-date version of the toolchain fixed an issue where GCC tried to link a soft-float math library for a hard-float build. I got the project to build by using the
-mfloat-abi=softfp option, but actually running a floating-point operation still caused the chip to crash. With this fresh toolchain, I can build with
-mfloat-abi=hard and my Cortex-M4F chip can calculate an arctangent 🙂
So maybe I was mis-configuring things, maybe I was using new configuration flags that the older toolchain didn’t recognize, maybe I forgot to install some library from the package manager, or maybe (against all probability) it was actually a compiler bug. But sometimes it makes more sense to just re-install the latest stable version of something instead of trying to muddle through a tricky issue which you can’t find much information about. Sure you can write a bug report, but if updating to a newer version fixes the bug, there’s probably not much point.
Anyways, happy compiling! And corrections are always welcome; like I said, I wrote this guide mostly because I messed the process up so many times before getting it to work, so…what does that tell you?