Prepare the source
The preprocessor expands #include and macros. Your headers and C source become input for the compiler.
SMALL PROGRAM. REAL BUILD FILES.
Start with a simple program. Pick your build system and target.
Take home a project you can actually compile.
Includes source, build files & step-by-step instructions.
AFTER YOU EXTRACT THE ZIP
A LITTLE CONTEXT GOES A LONG WAY
The preprocessor expands #include and macros. Your headers and C source become input for the compiler.
The compiler translates C into machine code, via assembly, creating an object file. Warnings help you spot mistakes early.
The compiler driver calls the linker to join objects and runtime libraries into your executable. Make or CMake coordinates these steps.
Your build machine runs the tools. The resulting program runs on the target platform. Native means both platforms match; cross-compilation means they differ. In compiler-building terminology, host is the machine running the compiler, and target is the machine it generates code for.
These starters target Linux, not bare-metal microcontrollers or native Windows. On Windows, use WSL with Linux tools.
Not necessarily. AArch64 needs a 64-bit ARM Linux OS. ARM hard-float needs a compatible 32-bit hard-float userspace and CPU/FPU. The processor model alone is not enough: check ABI, loader, libc version and target OS. A sysroot from the target or vendor SDK helps match headers and libraries.
An ARM executable cannot run directly on an x86 computer. Copy it to the compatible target and run it there. QEMU needs additional setup and matching runtime libraries; this tool does not configure it.
aarch64-linux-gnu- is a prefix naming a family of tools, such as aarch64-linux-gnu-gcc. A sysroot is a directory containing target headers and libraries. It is not the compiler directory. Leave it empty to use your cross compiler's built-in defaults, or provide a matching SDK sysroot. Never link ARM objects against host x86 libraries.
On Ubuntu/Debian, example packages are build-essential, cmake, gcc-aarch64-linux-gnu and gcc-arm-linux-gnueabihf. The downloaded README includes commands for your selection.
C99, C11 and C17 select the language version. Debug adds debug information; Release defines NDEBUG (disabling C assertions). Optimization is independent: -O0 makes stepping through code easier; -O2 is a common release choice. Strict warnings add -Wextra -Wpedantic to -Wall; they are not treated as errors.
Each generated configuration gets a separate build directory. If you manually override Make compiler or flags, clean first. For CMake, configure a fresh directory when changing toolchains; the toolchain is loaded before project().
Keep learning from the source: GNU Make manual · CMake toolchains · GCC sysroots · Debian AArch64 package · Debian ARM package