Choosing a Continuous Integration (CI) compiler

A bike chain close up

Linux-based gcc ARM cross compilers for bare metal targets

While looking for a gcc cross compiler to use for an EmbedOps project, I took a look at my options and found a few choices, each with advantages and disadvantages.

I wanted to set up an EmbedOps Continuous Integration (CI) environment for an embedded ARM processor project. The project doesn’t use an operating system, so it’s just a “bare metal” project. In case you’re not familiar with this concept, the compiler and its libraries need to know about your underlying system. If the system is capable of providing certain services, such as memory management, the requests from the program are passed down. Otherwise, it’s up to the compiler and libraries to provide those services.

The gcc development tools are built for a specific combination of: host (aka, your laptop) OS, host processor, target OS, target processor. There are many supported target operating systems and processors. For the EmbedOps build environment, I’m using an x86_64-based Debian Linux server. So, the setup is an ARM-based platform with no OS, and it will build on an x86_64-based Debian Linux server.

The usual suspects

For each Ubuntu/Debian version, there is a corresponding gcc version associated with it. If you use the apt-get package installation tool, you will get the associated version. See the table below for a few of these combinations.

The gcc-arm-none-eabi Packages on Debian Releases

Debian Release Debian version Debian Release date gcc-arm-none-eabi package version gcc version Release Date
Jessie 8 4.8.4-1+11-1 4.8 2014-12
Stretch 9 (previous) 15:5.4.1+svn241155-1 5.4 2016-06
Buster 10 (latest stable) 15:7-2018-q2-6 7.3 2018-01
Bullseye 11 (In test) 15:8-2019-q3-1 8.3 2019-02
— — — 9.3 2020-03
— — — 10.2 2020-06
         

The advantage here is that this is probably the easiest, standard, and most straight forward way to install the gcc compiler and tools. The downside is that you may wind up with a version of the gcc compiler and tools that is several major versions behind. In my case, due to compatibility issues with other components in the project, I had to stick to Buster, which gave me gcc version 7.3. Even though updates to the Buster distribution regularly appear, they do not include updates to gcc with a different major version number.

A second option is from the ARM web site. They provide an official release of the complete set of gnu tools. Several flavors of this are available for multiple host OS platforms, including Linux, Windows and MacOS. This is a good option because it’s the ARM official release, but the drawback here is that the releases are only updated a couple of times per year. This is probably fine for most applications. As a side note, ARM also offers a proprietary compiler/toolset that’s licensed for a fee. I didn’t consider that as an option for this project.

A Couple of Alternatives

While looking around, I came across the arm-gcc-xpack distribution. This distribution is based on the same gnu code base as the official ARM releases and the Debian releases. The difference here is that the xpack distribution is updated very frequently. It’s not tied to any distribution version like Debian is. And with its very frequent updates, it’s more likely to include the latest features and bug fixes than the official ARM releases. The only down-side of this distribution is that the installation is a bit non-standard. It installs into a folder local to the user who runs the installation script. This results in a non-standard location with an obscure path, which required two things:(a) The build scripts and path variables must be updated to point to the non-standard installation path. The executables will wind up in ~/xpacks/repo/@pack-dev-tools/... instead of the typical /usr/local/... (b) In Debian, the default user is root. If the installation is being performed as root, the installation directory will wind up being located in the user root‘s home directory: /root. For security reasons, the folder /root does not provide read access to the non-root users. That prevents non-root users from being able to access the installation directory and therefore using the tools. I addressed this by creating the container and installing most of the necessary components as root, then created the non-root user and switched to that before performing the tools installation. For security and sanity reasons, I set up CI environments to perform all the CI work as a non-root user.

This shows the non-standard installation path of the xpack compiler and associated tools

Yet another option is to pull in the gcc source code and build your compiler, libraries, and tools from scratch. The gcc tools have become a very mature project with many features, and this means there’s an enormous amount of code to be built. The compressed source code is about 118 MB! And that is just the compiler, not the libraries or the tools. This can be time-consuming even on a fast system. Considering that you can get a recent, pre-built copy, this doesn’t provide much benefit. The value here would be if a custom configuration was needed, but for my project that wasn’t the case. If you need the absolutely latest version (10.2 at the time of this writing), this is your only option.

Comparisons

I experimented with each one of these solutions. At the time of my experiment, both the xpack and the official ARM releases were both at version 9.3. I discovered that by using the current xpack compiler, the binary image was about 5% smaller than the one created by the older Debian distribution with the same settings. There were space savings in all three areas (.text, .data, and .bss). The Debian distribution contains version 7.3. The details are in the table below.

In each case, the same compiler settings were used:

  • -mcpu=cortex-m0 (Generate code for an ARM Cortex-M0)
  • -mthumb (Generate code that can call between ARM andThumb instructions)
  • -Os (Optimize for size)
  • -fsigned-char (Treat ‘char’ as ‘signed char’)
  • -ffunction-sections (Place each function into its own section in the output file)
  • -fdata-sections (Place each data item into its own section in the output file)
  • -g3 (Include extra debugging information)
  • -mfloat-abi=soft (Floating point math is performed in software)
  • -march=armv6s-m (Indicates what instructions are available for the processor)

Conclusion

For older ARM architectures, any of these solutions could suffice. The Debian solution will lag a year or two behind, whereas the official ARM and xpack solutions will be less than a year old. You also have the option to build the latest 10.2 compiler from the source code. For this project, I chose to go with the xpack solution, to take advantage of the latest fixes and updates without waiting for the next official ARM release.

If you want all of the benefits listed here and none of the hassle of setting them up or maintaining them, consider reaching out! At DojoFive, we have talented engineers on hand ready to help you with all aspects of your EmbedOps journey. We are always happy to help with interesting problems that need solving. You can reach out at any time on LinkedIn or through email!

Discover why Dojo Five EmbedOps is the embedded enterprise choice for build tool and test management.

Sign up to receive a free account to the EmbedOps platform and start building with confidence..

  • Connect a repo
  • Use Dev Containers with your Continuous Integration (CI) provider
  • Analyze memory usage
  • Integrate and visualize static analysis results
  • Perform Hardware-in-the-Loop (HIL) tests
  • Install the Command Line Interface for a developer-friendly experience

Subscribe to our Monthly Newsletter

Subscribe to our monthly newsletter for development insights delivered straight to your inbox.

Interested in learning more?

Best-in-class embedded firmware content, resources and best practices

Laptop with some code on screen

I want to write my first embedded program. Where do I start?

The boom in the Internet of Things (IoT) commercial devices and hobbyist platforms like the Raspberry Pi and Arduino have created a lot of options, offering inexpensive platforms with easy to use development tools for creating embedded projects. You have a lot of options to choose from. An embedded development platform is typically a microcontroller chip mounted on a circuit board designed to show off its features. There are typically two types out there: there are inexpensive versions, sometimes called

Read More »
Medical device monitoring vitals

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part 1

IEC-62304 Software Lifecycle requires a lot of self-reflection to scrutinize and document your development processes. There is an endless pursuit of perfection when it comes to heavily regulated industries. How can you guarantee something will have zero defects? That’s a pretty hefty task. The regulatory approach for the medical device industry is process control. The concept essentially states that if you document how every step must be completed, and provide checks to show every step has been completed properly, you

Read More »
Operating room filled with medical devices

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part II

Part I provides some background to IEC-62304. Part II provides a slightly more in-depth look at some of the specifics. The IEC 62304 Medical Device Software – Software Lifecycle Processes looks into your development processes for creating and maintaining your software. The standard is available for purchase here. So what activities does the standard look at? Here are some of the major topics. For any given topic, there will be a lot more specifics. This will look at a few

Read More »