CMake+GCC based offline build system with Mbed sources

You can build using offline toolchains.

Offline builds with actual sources allow for fine-grained control and support a much better debugging experience should anything go wrong. It is also a better learning experience to setup one of these.

Here's a complete setup for a Bluetooth-smart demo application built using arm-gcc and Cmake. Various people have contributed to it; many thanks go to Sandeep SS for contributing a working example of a build system.

Please be aware that if you choose to take this route, in some cases you may need to modify the build configuration files to point to the correct dependencies.

There are several license free toolchains for ARM Cortex-M cross compilation. I chose GCC ARM Embedded as the toolchain, and CMake as a cross-platform build-system generator.

Cmake is a very mature and highly configurable cross-platform build system supported by good documentation. It abstracts a Makefile like build system.

The following instructions apply to a Ubuntu development machine.

Create a directory to host files for your project; we'll refer to this as WORKSPACE_DIR, but you can choose any name for it.

CMake is driven by a collection of CMakeLists.txt file(s) spread across the sources. There needs to be at least one of these at the top level of the sources. Install this CMakeLists.txt under WORKSPACE_DIR. This file declares the dependencies and commands needed to generate the make files which will eventually build your project. We'll work with a single CMakeLists.txt file; you can change this for yourself if needed.

The CMakeLists.txt file describes the project dependencies using very simple, readable directives. It is what you would expect from a collection of toolchain-dependencies: include directories, compiler flags, sources [in C/C++ or assembly], the name of the final build target, and any custom post-build commands.

CMake is far more capable than what can be gathered from this simple example. The highly readable nature of CMakeLists.txt file works as an encouragement to refer to the documentation for CMake.

It its default state, CMakeLists.txt is meant for the BLE-HeartRate demo project. You may want to update the name of the project.

All mbed applications depend on the mbed-SDK. This is a Git repository, which can be cloned as:

$ git clone git@github.com:mbedmicro/mbed.git mbed-src

I typically clone that repository as mbed-src (as shown above). The actual mbed SDK resides under the subfolder libraries/mbed within mbed-src.

Bluetooth Smart applications meant for the Nordic platform also depend on the BLE_API, and nRF51822 libraries. These are mercurial repositories, which can be cloned as:

$ hg clone https://<replace-with-your-credentials-on-mbed-dot-org>@developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/
$ hg clone https://<replace-with-your-credentials-on-mbed-dot-org>@developer.mbed.org/teams/Nordic-Semiconductor/code/nRF51822/

You may need to update the references to these external dependencies in your CMakeLists.txt; if you're not building for Nordic or Bluetooth-smart, then these libraries may not apply to you at all. Please update the following as needed.

# define some more paths to projects we depend on
set (MBED_SRC_PATH     ${BLE_HEART_RATE_SOURCE_DIR}/../../mbed-src/libraries/mbed)
set (BLE_API_SRC_PATH  ${BLE_HEART_RATE_SOURCE_DIR}/../../BLE_API)
set (NRF51822_SRC_PATH ${BLE_HEART_RATE_SOURCE_DIR}/../../nRF51822)

The CMakeLists.txt file can be switched to using a different toolchain if you need; change the following to do that:

# Decide about the actual compilers to be used; uncomment one of the following.
set(TOOLCHAIN armgcc)
# set(TOOLCHAIN armcc)

CMake can drive a build to generate object files either alongside the sources or in any separate build workspace. The latter is preferable and easily accomplished. Create a Build folder under WORKSPACE_DIR, change directory to it, and run cmake passing the path to the top level CMakeLists.txt folder as a parameter. This looks like:

WORKSPACE_DIR$ mkdir Build
WORKSPACE_DIR$ cd Build
WORKSPACE_DIR$ cmake ..
    ...
    ... a lot of useful information emitted by CMake regarding build settings
    ...
WORKSPACE_DIR$ make

If everything goes well with 'make', you'll end up with an executable called 'combined.hex' which is ready to be deployed on the Nordic target. Running make with VERBOSE=1 command line option will expose the details about the commands being executed.


2 comments on CMake+GCC based offline build system with Mbed sources:

28 Jan 2014

Hello Rohit Grover,

thanks for this notepad. Looks promising. could you push a repo which would more described your working environment ? Would be easier for some to just pull a repository with like hello world, add mbed-src as you wrote and compile. How is CMake supported in IDE ? I haven't used it yet, so this could be a good starting point. That CMake is currently written for LPC1768 as I noticed, we can work on something more generic towards all supported targets.

I also saw CppTest which was one of things I wanted to push here, did not find it before that somebody would use test framework on mbed. Useful addition !

Regards,
0xc0170

28 Jan 2014

Hi Martin,

I've updated the notepad with a link to a skeleton repo. Yes, it is possible to simply add a library to this skeleton, make minor changes to CMakeLists.txt (under mbed-test) and build. CMake integrates very well with IDEs. There's documentation on the internet. Eclipse, for instance, is well supported. Otherwise, cmake essentially produces a Makefile and therefore can work with any IDE capable of understanding Make based systems. My CMakeLists.txt uses the compiler flags necessary for compiling with LPC1768. If you've got a different processor, you'll need to make very few changes: update compiler predefines, and update the startup files and linker scripts. The best way to go about this would be to create a sample blinkey program using the web-based mbed compiler, export that program to an offline toolchain [supported by the web interface], and then study the auto-generated Makefile to learn about compiler/linker settings. The differences are always minor.

Please log in to post comments.