Summary
The build of libnm for an ARM64 target inside a Docker container fails during the generation of the org.freedesktop.NetworkManager.policy file. The failure is caused by the msgfmt step being unable to locate ITS (Internationalization Tool Syntax) rules for the policy template, which is a typical issue when the build environment lacks the required locale and translation tooling for the target architecture.
Root Cause
- Missing ITS rules installation – The
msgfmtutility looks for ITS rule files in the system‐wide data directories. On a minimal Ubuntu 22.04 image used in the Dockerfile, these files are not installed by default, especially when cross‑compiling for ARM64 where the environment is even more stripped down. - Cross‑compilation quirks – Running
mesoninside a Docker container with QEMU leverages the host’smsgfmtbinary, which expects the ITS files at paths that don’t exist on the emulated ARM64 filesystem. - Inadequate build flags – The Dockerfile disables several optional components (e.g.,
--tests=no) but does not explicitly enable or install the locale and translation support packages needed for the policy generation step.
Why This Happens in Real Systems
- Container minimalism – Production containers often exclude development and translation tools to keep size small, which inadvertently removes dependencies required by certain build steps.
- Cross‑platform build pipelines – CI/CD infrastructure frequently cross‑compiles for multiple architectures. The underlying host binary (
msgfmt) interprets paths relative to its own architecture, causing path resolution failures. - Complex build systems – Libraries like libnm rely on Meson/Ninja pipelines that invoke multiple third‑party tools (e.g.,
msgfmt,polkit,gettext). A missing tool in the target image propagates as a seemingly unrelated build error.
Real-World Impact
- Stalled CI pipelines – Builds hang or fail mid‑process, increasing turnaround time and blocking feature releases.
- Deployment delays – Devices such as Raspberry Pi 4 cannot use updated NetworkManager APIs, limiting IoT deployments.
- Increased support burden – Engineers lose time debugging cross‑compilation errors that are actually packaging issues, diverting from feature work.
Example or Code (if necessary and relevant)
# Install gettext and ITS rule files, which provide msgfmt with the needed locales.
RUN apt-get update && \
apt-get install -y gettext libgettextpo-dev
How Senior Engineers Fix It
- Explicitly install translation tooling
Addgettextandlibgettextpo-devto the Dockerfile to supply ITS rule files and a fully featuredmsgfmt. - Set up the correct locale paths
ExportLANGUAGE=en_US.UTF-8andLC_ALL=en_US.UTF-8in the build environment so that Meson can locate the translation files. - Use
meson’s--force-fallback-foroption
When cross‑compiling, pass--force-fallback-for gettextto force Meson to use the locally installedgettexttools rather than the host ones. - Validate the build on a native ARM64 host first
Run the same Docker build on a real Raspberry Pi 4 to confirm that the issue is resolved before pushing to CI.
Why Juniors Miss It
- Assuming all build tools are available – Junior engineers often overlook the fact that container images can be stripped of development utilities.
- Misreading error messages – The
msgfmt: cannot locate ITS ruleserror is usually interpreted as a missing.pofile rather than an environmental missing dependency. - Lack of cross‑compilation experience – They may not realize that tools like
msgfmtbehave differently when invoked under QEMU, leading to path resolution failures.