MAVLink Router is an essential connection and routing component within a Micro-Air Vehicle architecture. It is an open-source C++ daemon for MAVLink message bridging.
Its build-time and run-time requirements include:
- C++ compiler and tools,
- standard C++ libraries,
- The
pkgconf
package configurator, - Meson and
- Ninja.
How does the embedded developer install this important tool on a Buildroot system? The solution is pretty straightforward; it requires
- a
mavlink-router.mk
Makefile, - a
Config.in
configuration file and - a package sub-menu.
Buildroot already supports Meson-based packages. However, some trickiness does exist: the source repo uses sub-modules; the Meson build script also assumes by default that the embedded target uses systemd
as the Linux service manager but such is not always the case.
Solution
Here is the solution for the impatient.
Configuration
Add a Config.in
menu item to the Buildroot packages under buildroot/package/mavlink-router
.
config BR2_PACKAGE_MAVLINK_ROUTER
bool "MAVLink Router"
help
MAVLink Router is an application to distribute MAVLink messages between multiple
endpoints. It distributes packets to a single port or multiple endpoints
depending on the target address. Connections can be made via UART, UDP or TCP.
https://github.com/mavlink-router/mavlink-router
Insert the following sub-menu directive just before the last endmenu
in buildroot/package/Config.in
. This connects the new package to the packaging system.
menu "MAVLink"
source "package/mavlink-router/Config.in"
endmenu
These kconfig
directives will make the “MAVLink Router” appear as an option in the Buildroot configuration menus.
Makefile
Add a new Makefile for the package, buildroot/package/mavlink-router/mavlink-router.mk
as follows.
################################################################################
#
# mavlink-router
#
################################################################################
MAVLINK_ROUTER_VERSION = 42529d55b665e0a9a29e424e186f514c56c2e5b5
MAVLINK_ROUTER_SITE = $(call github,mavlink-router,mavlink-router,$(MAVLINK_ROUTER_VERSION))
MAVLINK_ROUTER_SITE_METHOD = git
MAVLINK_ROUTER_GIT_SUBMODULES = YES
MAVLINK_ROUTER_LICENSE = Apache-2.0
MAVLINK_ROUTER_LICENSE_FILES = LICENSE
MAVLINK_ROUTER_INSTALL_STAGING = YES
ifeq ($(BR2_PACKAGE_SYSTEMD),y)
MAVLINK_ROUTER_DEPENDENCIES += systemd
else
MAVLINK_ROUTER_CONF_OPTS += -Dsystemdsystemunitdir=/usr/lib/systemd/system
endif
$(eval $(meson-package))
If the Buildroot has systemd
then the make script asserts it as a dependency. If not then it bypasses the Meson build dependency on systemd
by passing a custom systemdsystemunitdir
. Note also the site ‘method’—packages with Git submodules, as in this case, require git
as the pull method.
Alpine Comparison
Building on Docker using bare-bones Alpine Linux \(3.x\) can act as a boilerplate. A simple Docker-based deployment illustrates the Router daemon’s dependencies, both build and run-time requirements included. See below.
FROM alpine:3 AS builder
RUN apk update && apk add --no-cache \
gcc \
g++ \
git \
pkgconf \
meson \
ninja \
linux-headers \
&& rm -rf /var/cache/apk/*
RUN git clone --recursive https://github.com/mavlink-router/mavlink-router \
&& cd mavlink-router \
&& meson setup -Dsystemdsystemunitdir=/usr/lib/systemd/system --buildtype=release build . \
&& ninja -C build
FROM alpine:3
RUN apk update && apk add --no-cache libstdc++
COPY --from=builder /mavlink-router/build/src/mavlink-routerd /usr/local/bin
ENTRYPOINT [ "mavlink-routerd" ]
The dependencies match those of Buildroot.
Conclusions
Integrating the Router with Buildroot’s packaging system allows the package to correctly compile and link using the correct cross-compiling toolchain.
Gotchas exist as usual. The Router by default depends on systemd
for launching. But what if the target does not use systemd
? For example, it uses eudev
. The two are mutually exclusive. Choose one or the other. For non-systemd
Linux environments, the Meson build needs to know where to install its boilerplate configuration even though systemd
not present.