GCC (GNU Compiler Collection) - MarekBykowski/readme GitHub Wiki

GNU Compiler Collection (GCC)

GNU Compiler Collection (GCC) is a free and open-source compiler system produced by the GNU Project. Originally called the GNU C Compiler, it was expanded to support multiple programming languages and is now the standard compiler for Linux, embedded systems, and cross-platform development.


Name

GNU stands for GNU's Not Unix — a recursive acronym coined by Richard Stallman in 1983 as part of the GNU Project to develop a free Unix-like operating system.


Supported Languages

Language Frontend Command
C cc1 gcc
C++ cc1plus g++
Fortran gfortran gfortran
Ada gnat gnat
Go gccgo gccgo

All frontends share the same optimiser and backend — only the parser and AST differ.


Compilation Pipeline

source.c
   ↓  cpp          (preprocessor — expands #define, #include)
source.i
   ↓  cc1          (compiler — produces assembly)
source.s
   ↓  as           (assembler — produces object file)
source.o
   ↓  ld           (linker — produces final binary)
firmware.elf / a.out

Each stage can be run separately:

gcc -E source.c -o source.i      # preprocessor only
gcc -S source.c -o source.s      # compile to assembly
gcc -c source.c -o source.o      # compile + assemble, no link
gcc source.o -o firmware         # link only
gcc source.c -o firmware         # all in one

GCC vs MSVC

GCC MSVC
Vendor GNU Project Microsoft
Platforms Linux, embedded, Windows (MinGW) Windows
Object format ELF PE (.exe, .dll)
x86-64 calling convention System V ABI (args: RDI, RSI, RDX...) Microsoft ABI (args: RCX, RDX, R8...)
Used by Linux kernel, U-Boot, embedded Windows kernel, Visual Studio
Extensions __attribute__, __builtin_* __declspec, __cdecl

Embedded Cross-Compilation

For embedded targets, GCC is used as a cross-compiler — runs on the host machine but produces code for a different target architecture.

Toolchain Target Use case
arm-none-eabi-gcc ARM bare metal (no OS) Cortex-M MCUs, flight controllers
arm-linux-gnueabihf ARM Linux (hard float) Raspberry Pi, companion computers
aarch64-linux-gnu-gcc ARM64 Linux Jetson, modern SBCs
riscv32-unknown-elf-gcc RISC-V bare metal RISC-V MCUs

C Standard Flags

CFLAGS += -std=c99     # strict C99
CFLAGS += -std=c11     # strict C11
CFLAGS += -std=gnu11   # C11 + GCC extensions (most common for embedded)
CFLAGS += -std=gnu99   # C99 + GCC extensions

# Always recommended
CFLAGS += -Wall -Wextra -Wpedantic

💡 Most embedded projects use -std=gnu11 — gets C11 features plus GCC extensions that embedded code relies on heavily.


GCC Extensions

GCC adds extensions beyond the C standard, heavily used in Linux kernel and embedded firmware.

__attribute__

__attribute__((packed))              // remove struct padding
__attribute__((aligned(64)))         // force alignment
__attribute__((noreturn))            // function never returns
__attribute__((section(".ccmram")))  // place in specific memory section
__attribute__((weak))                // weak symbol — can be overridden
__attribute__((unused))              // suppress unused warning

__builtin_*

__builtin_expect(x, 1)        // branch prediction hint (likely)
__builtin_expect(x, 0)        // branch prediction hint (unlikely)
__builtin_popcount(x)         // count set bits
__builtin_clz(x)              // count leading zeros (UB on 0!)
__builtin_ctz(x)              // count trailing zeros (UB on 0!)
__builtin_bswap32(x)          // byte swap 32-bit
__builtin_bswap64(x)          // byte swap 64-bit
__builtin_unreachable()       // mark dead code path

Likely / Unlikely macros (Linux kernel style)

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

if (unlikely(error)) {
    handle_error();   // compiler moves this out of hot path
}

GCC on Windows

GCC does not natively produce Windows PE binaries, but several ports exist:

Port Description
MinGW GCC for Windows, produces native PE binaries
MSYS2 MinGW + package manager, popular for embedded toolchains
Cygwin GCC with POSIX compatibility layer
WSL Full Linux subsystem on Windows, native GCC

Most embedded developers on Windows use arm-none-eabi-gcc via MSYS2 or WSL.


GNU Toolchain

GCC is part of the broader GNU toolchain:

Tool Purpose
gcc compiler
ld linker
as assembler
objdump inspect object/binary files
objcopy convert binary formats (ELF → .bin, .hex)
nm list symbols in object file
size report text/data/BSS sizes
strip remove debug symbols
gdb debugger
glibc C standard library

Key Compiler Flags Reference

Flag Meaning
-c compile only, no link → produces .o
-o name output filename
-Wall -Wextra enable warnings (always use)
-O0 no optimisation (debug)
-O2 optimise (production)
-O3 aggressive optimisation
-Os optimise for size (embedded)
-g include debug symbols
-I path add include search path
-L path add library search path
-l name link library libname.a
-D NAME define preprocessor macro
-mcpu=cortex-m4 target CPU
-mthumb use Thumb instruction set
-fstack-usage report stack usage per function
-fno-exceptions disable C++ exceptions (embedded)
-ffreestanding no standard library assumed (bare metal)
-Map=output.map generate linker map file