# 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. ```bash # 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:** ```bash 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:** ```bash # 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: ```bash ./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:** ```bash 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): ```bash # 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: ```bash qemu-arm ./arm_binary # emulate ARM binary on x86 qemu-riscv64 ./riscv_binary # emulate RISC-V binary on x86 ``` See [[qemu]] for emulation.