Site Tools


wiki:gcc-cross-compilation

Table of Contents

GCC Cross-Compilation

Cross-compilation produces binaries for a different architecture than the build machine. Useful for embedded systems, bare-metal firmware, and HPC clusters with different CPU architectures.

# Build on x86, produce ARM binary
arm-linux-gnueabihf-gcc -o app app.c
 
# Build on x86, produce RISC-V binary
riscv64-linux-gnu-gcc -o app app.c

The compiler prefix indicates the target architecture. arm-linux-gnueabihf-gcc is the ARM cross-compiler (part of cross-compilation toolchain).

Installing cross-toolchains:

sudo apt install gcc-arm-linux-gnueabihf        # ARM
sudo apt install gcc-aarch64-linux-gnu          # ARM 64-bit
sudo apt install gcc-riscv64-linux-gnu          # RISC-V

Each toolchain includes the compiler, linker, and target C library headers and binaries.

Compilation flags for targets:

# 32-bit ARM (Cortex-A7/A9)
arm-linux-gnueabihf-gcc -O3 -march=armv7-a -mfpu=neon -o app app.c
 
# ARM Cortex-M4 (embedded, no OS)
arm-none-eabi-gcc -O3 -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -o app app.c
 
# RISC-V 64-bit
riscv64-linux-gnu-gcc -O3 -march=rv64imac -o app app.c

-march specifies the target architecture; -mcpu specifies the CPU model. Without these, the compiler uses a conservative baseline.

Cross-compilation with libraries: When using third-party libraries, compile them for the target architecture first:

./configure --host=arm-linux-gnueabihf  # tell build system target architecture
make
make install DESTDIR=/path/to/target

The --host flag tells the build system you're cross-compiling. It configures for the target, not the build machine.

Linking against cross-compiled libraries:

arm-linux-gnueabihf-gcc -I/path/to/target/include -L/path/to/target/lib \
    -o app app.c -lmylib

-I points to target headers; -L points to target libraries. The linker uses target libraries, not the host libraries.

Bare-metal (no OS): For firmware without an OS (microcontroller, bare-metal runtime):

# ARM Cortex-M4 (embedded)
arm-none-eabi-gcc -O3 -mcpu=cortex-m4 -mthumb \
    --specs=nosys.specs -o app.elf app.c
objcopy -O binary app.elf app.bin

arm-none-eabi-gcc (no Linux) targets bare metal. --specs=nosys.specs removes OS dependencies. objcopy converts ELF to raw binary for flashing.

Testing cross-compiled binaries: You can't run a cross-compiled ARM binary on x86. Test on actual hardware or use an emulator:

qemu-arm ./arm_binary      # emulate ARM binary on x86
qemu-riscv64 ./riscv_binary  # emulate RISC-V binary on x86

See QEMU for emulation.

wiki/gcc-cross-compilation.md · Last modified: by 127.0.0.1