5.3.10 · D1Build Systems & Toolchain

Foundations — Cross-compilation — toolchains, sysroot

1,885 words9 min readBack to topic

Everything in the parent note — triplets, toolchains, sysroots, ABIs — is a consequence of that one idea. This page builds each word you need, starting from "what is a machine instruction," so that not a single symbol in the parent arrives unexplained.


0. The very bottom: what a program is

Figure — Cross-compilation — toolchains, sysroot

Look at the figure. The same high-level line x = a + b; becomes completely different bit patterns on two CPUs. An x86 chip reading an ARM pattern is like a French speaker reading Japanese characters — the marks mean nothing to it. This single fact is why cross-compilation must exist: a binary is not portable across CPU families.


1. From source to binary: the pipeline of tools

The parent lists gcc, as, ld, ar, objcopy... as members of a "toolchain." To know why each exists you must see the assembly line they form.

Figure — Cross-compilation — toolchains, sysroot
Recall Why does an object file have "blanks"?

Because when the compiler processes one .c file, it doesn't yet know where printf (defined elsewhere) will end up in memory. It leaves a symbol placeholder; the linker fills it once all files are on the table. :::


2. Libraries: the promises the linker must keep

When your code calls printf, that code lives in someone else's file. That file is a library.

Figure — Cross-compilation — toolchains, sysroot

3. ABI: the invisible handshake

The parent's trickiest field is gnueabihf vs gnueabi. To understand it you need one more word.


4. Assembling the vocabulary: the triplet, decoded

Now every field of <arch>-<vendor>-<os>-<abi/libc> is earned:

Field Word we built It answers
<arch> ISA (§0) Which machine instructions?
<vendor> (labeling only) Who made/branded it? Often unknown.
<os> operating system Is there a kernel providing printf, files, threads? none = bare metal.
<abi/libc> ABI + C library (§2,§3) Which calling rules and which libc (gnu, musl, newlib)?

5. Build vs Host vs Target — grounded now

With "where does code run" made concrete, the three roles fall out:


The prerequisite map

Machine instruction = bits one CPU obeys

ISA = the arch field

Object file + symbols

Linker resolves symbols

Libraries static and dynamic

Headers describe layout

Sysroot = target root folder

Triplet arch vendor os abi

ABI = binary handshake

Toolchain matched to triplet

Cross-compilation

build host target roles


Equipment checklist

Test yourself — cover the right side and answer aloud before revealing.

Why can't you copy an x86 binary to an ARM device?
The bytes are x86 machine instructions; the ARM CPU cannot decode a different ISA's instruction patterns.
What is a symbol in an object file?
A named blank (like printf) left by the compiler for the linker to fill in with a real address.
What does the linker do that the compiler cannot?
Combine many object files plus libraries and resolve every symbol to a concrete address, producing the final executable.
Static library vs dynamic library — one-line difference?
Static code is copied into your binary at link time; dynamic code stays separate and is loaded at run time.
Why must the sysroot hold BOTH headers and libraries?
Headers give the compiler the target's struct layouts and prototypes; libraries give the linker the target's actual machine code.
What is an ABI, and why can a mismatch link but still crash?
Binary-level calling rules (registers, stack, float placement); names still match so linking succeeds, but the two sides disagree on where data sits at run time.
Decode aarch64-none-elf.
64-bit ARM ISA, no operating system (bare metal), ELF output, no assumed libc.
When is a compile a "cross" compile in terms of build/host/target?
When the host (where the compiler runs) differs from the target (where the output runs).
What does --sysroot=S do to a default include path /usr/include?
Rewrites it to S/usr/include, relocating the search root to the target tree.