I am porting libopencm3’s build system to Meson. I’ve used Make for a long time. Here’s why I want to use Meson for new projects.
Meson puts me in charge of dependency integration, not some vendor or SDK. I don’t want to copy files into my source tree or be tied to some “workspace” that an IDE requires. I want to point at a Git commit. Git submodules are too hard to delete. I’ve written about this.
The Meson language is well designed and specified, inspired by Python rather than shell. Two implementations of Meson exist: Meson proper, written in Python; and Muon, written in C. These are a sign of maturity.
Meson suits the needs of a microcontroller project. It has good support for cross-compilation. It supports only out-of-tree builds, so creating and comparing builds with different configurations is easy.
The Meson port builds code at a speed similar to the original build system. When building all targets, Meson is only slightly faster. When building a subset of targets, Meson is faster due to better dependency tracking for generated interrupt code. (Both build systems have a syscall bottleneck, which I believe is due to filesystem I/O.)
A project using Meson can add CMake projects as dependencies. CMake is used by some popular embedded projects, such as FreeRTOS.
The Meson port builds all targets. It supports building a subset of targets when used as a Meson subproject. I’ve been testing the STM32F4 target on an example project. This project has been running well on the stm32f4-discovery development board. I have not run code for other targets. The port does not yet support running libopencm3’s tests or building Doxygen documentation. The port does not interoperate with libopencm3’s examples or template repositories.
Don’t break the original build system.
Avoid changing existing files. Adding new files is OK.
Write idiomatic Meson code.
Support operating as a Meson subproject.
Match the original toolchain invocations as closely as possible.
The port was created by manual and automated processes. An Awk script translates target Makefiles into Meson code. To simplify the script, I changed a few Makefiles to be more uniform. Meson assumes that source files with a .c extension are valid translation units. This isn’t true in the case of vector_nvic.c: it is not compiled itself, but is included by another file. I worked around this by changing the filename to vector_nvic.h.
The port has four build-time dependencies: Meson (obviously), Python (which was already used), Ninja, and Awk. The Awk script is checked in. (It may be removed if the two build systems no longer need to be synchronized.) Ninja is widely available. There is also a Ninja-compatible alternative called Samurai, written in C.
If upstream were to consider accepting Meson support for libopencm3, they should think about:
Do we want to have two build systems, or just Meson?
When Qemu ported to Meson, it removed its original build system for fear of increasing maintenance burden on contributors. Qemu’s at least ten times bigger than libopencm3 and much more complex, so this isn’t surprising. libopencm3 may or may not want to have two build systems. If we remove the original build system, we’ll have to port (or abandon) the examples and template repositories.
Removing the original build system might allow a different source tree structure. libopencm3 uses the C preprocessor to control what code is part of a target. With Meson, there might be other options.
Discuss this page by emailing my public inbox. Please note the etiquette guidelines.
© 2024 Karl Schultheisz