At MIND, we use XMOS microcontrollers in some of our boards to take care of all low level functionality of the ELK Platform, such as interfacing with codecs, handling GPIO’s, USB audio interface etc. It is capable of performing multi-threaded workloads in an extremely deterministic manner. Utilising their “multi-tiled” architecture, it offers a lot of flexibility and parallelism for the programmer to distribute workloads in a very efficient way. Moreover, XMOS also offers a lot of supporting drivers and utilities to help realise the programmers goals faster with minimal development time.

However, the XMOS build system has limited functionality and is closely tied to how the xTimeComposer (their IDE) manages their builds. It offers lower flexibility than CMake and can leave much to be desired. This blog post is about how to use CMake, a very popular build process management tool, to compile XMOS code without using the IDE.

The Problem with THE XMOS Build System

The XMOS build system does not use the conventional approach of using a “main.c” that links to static libraries, but rather use a different terminology such as “apps” (which refer to applications) and “modules” which refer to libraries. A basic form of a Makefile generator is used, where a small subset of preprogrammed options can be specified depending on the needs of the application. As mentioned before, the build system is quite intertwined with the use of their Eclipse based IDE called xTimeComposer, and is intended to reduce the learning curve and to get started as soon as possible.

As an example, let’s consider their application note AN00160 which gives a tutorial on how to use their SPI module (links at the end of the blog). As it can be seen from AN00160’s Makefile, there are very few configuration options that allow us to customize the build. Below are a few cons I faced when using this method:

  • Single binary target for one Makefile – This build system forces us to create another “app” with another Makefile if we want to have a slightly different target (say testing of SPI) rather than just building the test program along with the main application.
  • Few build options : It does not allow custom build options. Such use cases can be an option which enables another module to be compiled in, or one which adds extra compiler flags or definitions. For the entire set of Makefile options, refer ti the links section of this blog.
  • Cluttered Directory Structure : As mentioned before, adding a new application for each target results in a messy directory structure.

Using the CMake Build System

At the end of the day, the XMOS code still has source files, include headers and libraries, which means that a far better platform independent build system like CMake can be used through a cross compilation technique. Do note that this is intended to be used with the command line and not the IDE.

  • First, the toolchains should be added to the path. xTimeComposer already has a shell script which sets up everything. In your terminal enter:
  • Now cmake can be configured to use the XCC compiler.
  • The target board can specified with the flag “-target=” option, which can be added to the CFLAGS. You can optionally add all other XMOS flags here such as “-fxscope” and “-report”. For AN00160, the target board is the SLICEKIT-L16.
  • The linker should also know which board it should link against.
  • Since XMOS source files have the .xc extension, CMake will complain that it does not know the linker language. Hence, we need to specify the language for all the source files in the project.

That’s it! Now you can specify your targets in CMake and use the xmake command to build. You can also structure your code in folders in a manner of your choice than to use the “app” and “module” approach. To run it in the device with the JTAG, run  xrun <xe binary name> or xlfash if you want to flash, using a terminal of your choice.

The CMakeLists.txt file for AN00160 is shown below. Do not that the module lib_spi is present inside the AN00160 directory, which is usually not the case when we use xTimeComposer.

For any further questions on this (or anything else) please write to us at

Links :


XMOS SPI Library 

XMOS Makefile Options

© 2019 Elk All Rights Reserved

Related All Tech

27 November
Elk Audio OS update!

13 May
The Audio Programmer Virtual Meetup

29 April
Elk Audio OS ♥ HiFiBerry

17 April
Introducing the BLACKBOARD

06 April
Raspberry Pi 4 support

14 February
Advice on Developing with Elk dev kits - Part 1

21 January
Sensei - Standing in the way of control

20 January
CCRMA Workshop

27 November
ADC19 - Talk

30 August
Elk on the I.MX8M Mini!

16 August
std::algorithm for audio, part II

16 August
Controlling plug-ins in Elk, part II:

20 June
std::algorithm for audio, part I

04 June
Controlling plug-ins in Elk, part I:

27 March
Audio Latency demystified, part II:

15 March
Audio Latency demystified, part 1

01 March
Discover the DAW inside Elk

26 January
ELK Development Boards Overview

23 January
How Elk works