User Tools

Site Tools


raspberry:cross-platform-compile:cross-compile-overview

This is an old revision of the document!


Cross Platform Development for Raspberry


Cross-development means developing and compiling programs on another platform then it intended to run upon. It is a common approach for Pi, since it’s also how Raspian is built. For quite some time I did compile Pi applications on the Pi itself. Which works quite well, but has one large drawback: performance. Being able to compile these programs on my 8 core 16GB desktop, improved compilation time enorm. And it is quite simple.

There are multiple approaches to setup a cross-compile environment. The most essential aspect is the following:

  1. Exact identical Linux/Debian versions on X86 build host and Raspberry runtime target
  2. Different Linux/Debian versions on X86 build host and Raspberry runtime target

crossbuild-essential-armhf

Compatibility rule

Build against the oldest operating-system release and CPU that the resulting binary must support. Do not link a Bookworm target against Trixie ARM libraries. Doing so can create dependencies on newer glibc or library symbols that are unavailable on the Bookworm target. For example:

Incorrect:
Trixie compiler + Trixie armhf libraries -> Bookworm target

Correct:
Trixie compiler + Bookworm armhf sysroot -> Bookworm target

The problem with different host and target ARM libraries

The important guideline is that the target system's ABI, headers, libraries and library versions vs. what you build against. For example:

                    HOST
              Debian Trixie x86-64
                     │
                     │ cross compiler
                     ▼
             arm-linux-gnueabihf-gcc
                     │
             ┌───────┴────────┐
       WRONG approach     CORRECT approach
             │                │
             ▼                ▼
    Trixie armhf libs    Bookworm Raspbian armhf libs
             │                │
             ▼                ▼
       ARM executable    ARM executable
             │                │
             └───────┬────────┘
                     ▼
              Raspbian Bookworm

Suppose your x86 host is Debian Trixie, and you install libc6:armhf from Trixie. Your compiler might then build against something like glibc 2.41 while your Raspberry Pi's Raspbian Bookworm has glibc 2.36. Your executable may therefore acquire a dependency on a newer GLIBC symbol. For example, conceptually:

program
  └── was linked against and requires GLIBC_2.41
             │
             ▼
       Raspbian Bookworm only has GLIBC_2.36
             │
             ✗
       program won't run, with errors like:
       ".../lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.41' not found..."

This is one of the most common reasons why building on a newer distribution for an older target causes trouble. It isn't only the libraries that matter. The headers matter too. Suppose you compile against Trixie's headers (/usr/include), but run on Bookworm. You can potentially get differences in:

  • API definitions
  • feature macros
  • structure definitions
  • constants
  • kernel interfaces
  • glibc interfaces
  • library-specific APIs

So the ideal relationship is:

That's why a target-specific sysroot is the clean solution.

But the reverse is usually fine

If you deliberately want to require a newer target system, that's perfectly legitimate. For example:

Build against Trixie armhf
          ↓
Deploy only to Trixie armhf
          ↓
      No problem.

The rule is simple: Don't build against a newer userspace than the oldest target you intend to support. This is particularly important for glibc.

Raspberry Pi OS vs Debian armhf

One important distinction: Raspberry Pi OS vs Debian armhf. Raspberry Pi OS is Debian-derived, but its 32-bit repository contains packages built for Raspberry Pi hardware and may contain versions or patches marked with +rpt. Use the Raspberry Pi OS repositories when Raspberry Pi OS is the target. Use Debian repositories only when the target is Debian armhf.

If your target is Raspberry Pi OS 32-bit, don't blindly assume that Debian Bookworm's armhf libraries are an exact match. Debian itself points this out:

Raspberry Pi OS armhf can be subtly incompatible with Debian armhf.

In particular, Raspberry Pi OS/Raspbian has historically had differences in its ARM ABI/build configuration. Debian recommends using a target-specific chroot when cross-compiling packages for Raspberry Pi OS armhf. ([Debian Wiki][2])

Links

raspberry/cross-platform-compile/cross-compile-overview.1788502325.txt.gz · Last modified: by oscar