Fix libnm Docker ARM64 Build Failure with gettext Installation

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 msgfmt utility 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 meson inside a Docker container with QEMU leverages the host’s msgfmt binary, 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
    Add gettext and libgettextpo-dev to the Dockerfile to supply ITS rule files and a fully featured msgfmt.
  • Set up the correct locale paths
    Export LANGUAGE=en_US.UTF-8 and LC_ALL=en_US.UTF-8 in the build environment so that Meson can locate the translation files.
  • Use meson’s --force-fallback-for option
    When cross‑compiling, pass --force-fallback-for gettext to force Meson to use the locally installed gettext tools 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 rules error is usually interpreted as a missing .po file rather than an environmental missing dependency.
  • Lack of cross‑compilation experience – They may not realize that tools like msgfmt behave differently when invoked under QEMU, leading to path resolution failures.

Leave a Comment