Automated Build Process@2x

Why automate embedded software build?

The first step in continuous integration and test automation is to have an automated build process. To automate embedded software build you need to have a system that can compile and build your code after you push a code change. If we take the following development cycle: edit -> compile -> test, having the compilation and building phase automated and triggered upon every code push has the following benefits:

  1. Productivity improvement.
  2. Catching compilation errors right on the spot, before it gets to other team members’ code base.
  3. Having a clean firmware executable ready for tests all the time.

In this post, I’m going to review build tools that you can use to automate embedded software build process. My goal is that you’ll connect a source control event to a build tool that will automatically compile and link the firmware binary and will run tests on it. This is the basic step of a continuous integration process (in the next blog post I’ll cover the rest of the process).


Let’s start then


GNU Make is one of the most popular build tools. It’s been around for a long time now. GNU Make is open source and is using a “makefile” to understand how to build your program. This “makefile” lists each of the non-source files and how to compile/link it from the other files.


  1. Easy to install on Linux and Mac and doesn’t have many dependencies.
  2. Not limited to any particular programming language.
  3. Automatically figures out which files need to be updated to save compilation time.
  4. Not limited to building code, can be used to run any CLI commands you want.


  1. Writing a “makefile” from scratch is not an easy task for starters.
  2. Hard to maintain over time.
  3. Non-intuitive scripting language.

GNU also has Autotools which extends GNU Make with a more extensive library of default build rules, plus extensive dependency checking capability.


Cross-platform Make is also one of the most popular build tools used by programmers for a long time. CMake is open source, and it generates “makefiles” based on the platform you’re using. As such in CMake, you first need to setup your build environment (by typing cmake <source_dir> in your build directory for example).


  1. Cross-platform, both in the sense of OSes and build systems.
  2. A single CMake config file can generate a native build system for Make, Eclipse, Visual Studio, etc.
  3. Automatic external library detection and configuration.
  4. Automatic discovery and configuration of the toolchain.
  5. More straightforward to compile your files into a shared library in a platform agnostic way,
  6. Generally easier to use than make.


  1. Updates are rolled continuously, so when working with more than one developer, you need to synchronize versions to make sure your code can be built.
  2. Nonintuitive scripting language.


SCons is an open source cross-platform software construction tool. It is based on Python. This means you can make the build system do pretty much anything you code in Python if it doesn’t do it already. This also means it doesn’t reinvent the wheel and uses a tried-and-proven syntax.

When compared to CMake, SCons is: slower, require more code for common tasks and is a bit less stable.

Python can be an advantage or disadvantage – depending on the developer.


  1. Autoconfiguration capabilities.
  2. Can be distributed with the software product, so users do not need to install it.
  3. No need for intermediate steps like generating a makefile and then using a makefile.


  1. A bit low-level; even some quite common tasks require writing more code than you’d expect.
  2. Dependency checking needs to be done manually.
  3. Slower then CMake.


Rake is an open source build software implemented in Ruby (tasks and dependencies are specified in standard Ruby syntax). Rakefiles are defined in standard Ruby syntax, which is available on many platforms. Derived from C, the Ruby syntax takes a little bit to get used to.


  1. Very powerful and flexible (supports subroutines, call tasks from other tasks, task are cumulative, etc.)
  2. Language-agnostic as far as the target build is concerned (includes cross-compiling toolchains for embedded targets).
  3. Does not rely on the host environment for simple operations like file or directory manipulation.
  4. Easy access to standard shell operations.


  1. Most embedded developers are not familiar with Ruby.
  2. Lacking much of SCons’ target-type-specific support.

Let’s Recap

In most cases, the build tool you’ll choose to work with is the one you have ready-made templates from your platform provider. This is natural as you want to make things fast and easy and automate embedded software build process is not an exception! For example, Nordic’s SDK samples come with Makefiles and Ceedling by ThrowTheSwich uses Rake.

Take a look at this example for how to setup STM32 build server using Make.

It’s common to start with one build tool and move to another one, which is more suitable for your needs as the project progresses. The most important thing though is using a build tool that allows you to automate your build process.