Programming · free software · the open webSubscribe via RSS

Cross compilation: build, host and target are different questions

The build, host, and target labels describe a compiler’s own construction and output roles. Ordinary package cross compilation adds separate questions about headers, libraries, and where the result can run.

Three machines in a toolchain

In GCC configuration, build is the machine on which the compiler is built, host is the machine on which that compiler will run, and target is the machine for which it generates code. A native compiler usually has the same machine in all three roles. A cross compiler separates at least the host and target: it runs on one system while producing code for another [1].

These labels describe the compiler toolchain. They are not a complete description of every package build. When building an application for an embedded board from a workstation, the workstation is the build machine, the compiler usually runs there, and the board is the application’s runtime destination. People often call this cross compilation even though GCC’s build-host-target terminology is being applied to the compiler itself.

Follow one application build

Imagine compiling a network client on an x86-64 workstation for a 64-bit ARM Linux device. The cross compiler executable runs on x86-64, but emits ARM instructions. The resulting executable is normally not runnable on the workstation: its instruction set and often its operating-system ABI differ.

The compiler also needs the target environment to compile and link correctly. A sysroot supplies a target-shaped filesystem view, commonly including system headers and libraries. Headers determine declarations and type layouts visible during compilation; libraries provide implementations and ABI-compatible symbols at link time. Pointing the compiler at the right output architecture without the matching target dependencies can produce failed includes, unresolved symbols, or a binary that expects an incompatible runtime.

A compiler is only one ingredient

Installing a cross compiler does not automatically provide every dependency of an application. A library that the program uses may need its own target build, and its dependencies may need to be built for that same environment too. Package configuration must find the target versions rather than accidentally selecting similarly named libraries from the workstation.

This is where build systems need clear distinctions between tools that run during the build and artifacts that become part of the target program. A code generator may need to run on the workstation, while the generated library needs to be compiled for ARM. Treating both as target artifacts can make the build attempt to execute an ARM program locally; treating both as host artifacts can silently link the wrong library.

Execution and verification choices

A target executable can be copied to the actual device for execution, or run under an emulator when one supports the needed instruction set and operating-system behavior. Emulation can make automated checks practical, but it may not reproduce device-specific peripherals, timing, kernel features, or deployment configuration. The choice depends on what the program relies on.

Keep the questions separate: where is each build tool run, what machine does each output execute on, and which headers and libraries define its ABI? GCC’s configuration guide defines build, host, and target for its own compiler configuration [1]. Answering the runtime and dependency questions for an ordinary package then turns those labels into a concrete, reproducible build setup.

References

  1. GCC configuration: build, host and target

Suggest a correction · All posts