yotta, cmake, ninja build tools for the Micro:bit explained

Understanding the offline build tools for the BBC Micro:bit

I use the offline build tools from Lancaster University for compiling and building C-code for the BBC Micro:bit board. I used the toolset without really understanding what was going on under the hood. Understanding our tools gives us a better chance of fixing things when they fail. So I spent a happy afternoon learning about these tools and how they differ from the system I was using for building C-code into executables. These executables are often called binaries.


yotta is a tool created at mbed to build C code aimed at a range of ARM processors into executable files. The processor on the BBC Micro:bit is an ARM processor. yotta is written in python so python needs to be installed on your system for yotta to run.

yotta uses a file called module.json containing information about the target platform. This information is used by yotta to download files that are required for your target hardware platform to enable your C code to work on that platform. These files are downloaded to a directory named yotta_modules. These files are used during the build process.

An example module.json file for the BBC Micro:bit is:

[code language="shell" light="true"]
"name": "microbit-c",
"version": "2.0.0-rc8",
"description": "The micro:bit runtime common abstraction with examples.",
"license": "MIT",
"dependencies": {
"microbit": "lancaster-university/microbit"
"targetDependencies": {},
"bin": "./source"

In the file yotta_targets/bbc-microbit-classic-gcc/target.json is a line:
[code language="shell" light="true"]
"toolchain": "CMake/toolchain.cmake",

This tells us that the CMake build system is used by yotta. So, what is CMake?


CMake is a command line tool that uses a file called CMakeLists.txt to create a list of shell commands that are run in a later stage to create the final executable for a C  project. This list of commands ends up in a file called Makefile. The CMakeLists.txt file contains things such as the flags passed to the compiler used to build the executable and the source files to be used in the build process.

Here I digress into the build system I am used to seeing, which uses ‘make’ to create the final binary executable. make is replaced by ninja in the Micro:bit build system. I cover this in the next section.

Github projects often use CMake to enable you to build the project’s source code on your system. To build these projects you often run the command ‘cmake’, which takes the CMakeLists.txt file in the github project and uses this to create the file Makefile. Then, running the command ‘make’ causes each of the commands in Makefile to execute.

As Makefile was created using cmake, the shell commands in Makefile will be the compiler commands to:

  • create .o files for all of our .c files

  • link these .o files together

  • create a /build/src directory

  • place the linked executable into this directory.

Often we run ‘make install’ to complete the installation of the binaries created from C code. The final output from running the commands in Makefile is often an executable binary file. The ‘install’ command copies this to wherever it needs to be in your system for it to run from the command line.

Digression ends.

But, but, but – the Micro:bit build system does not use ‘make’ to build the binary executable. Instead, it uses ninja.


If you can see the ninja, you are already dead.

ninja replaces make. make has been around for decades. Which is no bad thing. But somebody, somewhere, decided to make a better make.

One of the design goals for ninja is:

very fast (i.e., instant) incremental builds, even for very large projects

A quick search found somebody has compared the speed of make and ninja:

jpopsil – reports an increase in speed using ninja.

ninja creates a file called rules.ninja and build.ninja. ninja looks for build.ninja and uses this file to create the executable. If we look in rules.ninja, we see, well, some rules for how to build the executable. Looking in build.ninja…. there’s a lot of things. From reading the documentation, one of the ideas behind ninja is that all the decisions about how to create the executable are taken prior to the build. It looks like build.ninja has all of these build decisions in it. This allows ninja to do its job and create the binary without having to think too much along the way about what to do.

Edit April 2019

I found an excellent explanation of the micropython stack by Steve Stagg, who clearly understands the tool chain far better than I, about 3/4 of the way down this link:


This post refers to the micropython stack for the BBC Micro:bit, which  is built on top of the C stack.

The author has a picture, which shows the tool chain to be like this:





gcc g++ ld

According to the post ‘Micropython has some extra build stages, so has a Makefile wrapper around yotta,….’. So the make module at the top refers to the micropython implementation.  The post goes on to explain that  Yotta creates the CMake config file. I think I got that in this post as well. Ninja then builds this configuration. So far so good. Looks to be in agreement with what I wrote above. Steve has more details about what the ninja does when it runs. His post is worth a read.




Leave a Reply

Your email address will not be published. Required fields are marked *