5.3.10Build Systems & Toolchain

Cross-compilation — toolchains, sysroot

2,255 words10 min readdifficulty · medium

WHY does cross-compilation even exist?


WHAT is a "triplet"?


WHAT is a toolchain?


WHAT is a sysroot, and WHY is it the crux?

Figure — Cross-compilation — toolchains, sysroot

HOW: a full worked compile


Common mistakes (steel-manned)


Flashcards

What does cross-compilation mean?
Building on one machine (host) a program that runs on a different machine/architecture (target).
In compiler vocabulary, what are build/host/target?
build = where compiler is built; host = where compiler runs; target = what the output runs on.
What is a target triplet and its shape?
A name for a platform: <arch>-<vendor>-<os>-<abi/libc>, e.g. arm-linux-gnueabihf.
What is a toolchain?
The full matched set of tools (gcc, as, ld, binutils, target libc + headers + startup files) all for one target triplet.
What is a sysroot?
A directory tree mimicking the target's /, holding target headers (usr/include) and libs (usr/lib), found via --sysroot.
Why is a sysroot needed instead of host /usr/include?
Host headers/libs are for the host ISA/ABI; linking them produces a broken binary. Sysroot supplies the target's headers and libs.
How does --sysroot=S change search paths?
Every default root-anchored path p becomes S+p (e.g. /usr/include → S/usr/include), like a chroot for the compiler.
What does none in aarch64-none-elf imply?
No OS (bare metal); no libc assumptions — you must provide startup and runtime yourself.
Why do autotools need both --host and --build?
Their inequality signals a cross build, disabling run-tests that would execute target binaries on the host.
What does -ffreestanding do?
Tells the compiler there's no hosted runtime/libc; main isn't special and standard library functions aren't assumed.
Difference between gnueabi and gnueabihf?
Soft-float vs hard-float ABI; floats pass in integer regs vs FPU regs. Mixing them link-OK but crashes at runtime.
How do you verify a produced binary targets the right CPU?
Run file binary; it prints the architecture (e.g. "ELF 32-bit ARM").

Recall Feynman: explain to a 12-year-old

Imagine you can only write letters in English, but your friend reads only French. You don't mail them English — you translate first. Cross-compiling is your computer translating a program into the "language" (machine code) of a totally different computer, like a tiny robot. But translating words isn't enough: you also need the friend's dictionary so you use their words for things. The sysroot is that borrowed dictionary — a copy of the robot's own files, so your computer builds the program the way the robot expects, not the way your computer would do it for itself.

Connections

  • Linkers and the linking process — sysroot changes where ld resolves symbols.
  • ELF object file formatfile/objdump read the ELF arch field you're targeting.
  • ABI and calling conventions — soft-float vs hard-float lives here.
  • Build systems CMake and autotools — how --host/toolchain files wire in a cross compiler.
  • Chroot and namespaces — sysroot is "chroot for the compiler."
  • Static vs dynamic linking — sysroot must hold the right shared libs for the loader.

Concept Map

builds for

motivates

separates

separates

names

configures

used as prefix

includes

includes

provides

links against

means

part of

Host machine runs compiler

Target machine runs output

Target too small or bare

Cross-compilation

Target triplet arch-vendor-os-abi

Toolchain

gcc as ld binutils

Sysroot

Target libs and headers

os field none

No libc bare metal

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Cross-compilation ka matlab simple hai: aap apne bade x86 laptop (host) par ek program banate ho jo chalega kisi dusre chote device (target) par — jaise ARM router, Raspberry Pi, ya ek bare-metal chip. Target par khud compiler chalana mushkil ya impossible hota hai (RAM kam, OS nahi, slow), isliye banate yahan ho aur final binary wahan bhej dete ho. Lekin dhyan rakho — normal gcc apne hi machine ke instructions banata hai, isliye humein ek cross toolchain chahiye jaise arm-linux-gnueabihf-gcc, jiska prefix hi target ka triplet hota hai (arch-vendor-os-abi).

Ab sabse important cheez: sysroot. Jab aap #include <stdio.h> likhte ho aur printf use karte ho, compiler ko target ke headers aur libraries chahiye, host ke nahi. Agar galti se laptop ka /usr/include aur libc.so use ho gaya, to aap x86 ka code ARM binary mein ghusa doge — sab toot jayega. Sysroot ek folder hota hai jo target ke / ki nakal hai (usr/include, usr/lib). --sysroot=/path dene se compiler wahin se headers aur libs uthata hai — bilkul chroot jaisa, root hi shift ho jaata hai.

Practically yaad rakho do baatein (yeh 80/20 hai): (1) triplet end-to-end match hona chahiye — CPU, OS, aur float ABI bhi (gnueabi vs gnueabihf ka fark crash kara deta hai). (2) sysroot sahi se set ho. 90% cross-compile errors inhi do mein se ek hote hain. Aur ek chhota verify trick: binary banne ke baad file hello chala kar dekho — agar "ARM" likha aaya to sahi, agar "x86-64" to galat compiler use hua. Pehle predict karo, phir verify karo.

Go deeper — visual, from zero

Test yourself — Build Systems & Toolchain

Connections