A cross compiler is a compiler capable of creating executable code for a platform other than the one on which the compiler is running. A gcc-arm cross compiler is a version of the GNU Compiler Collection (GCC) that is designed to generate code for ARM processors while running on a different platform, like x86.
Cross compilers are commonly used in embedded systems development to build code for microcontrollers and other resource-constrained devices. Since these targets lack the memory and processing power to compile their own code natively, cross compilation provides a solution.
Why Use a Cross Compiler?
Here are some of the main reasons to use a gcc-arm cross compiler:
- Compiling natively on ARM devices is slow due to limited performance.
- Some ARM platforms like bare-metal microcontrollers don’t have an OS or toolchain.
- Cross compiling frees up the target system and allows for faster builds.
- Easier to integrate cross compiler into automated build environments.
- Allows ARM code to be developed on faster x86 desktops and laptops.
The gcc-arm cross compiler is included in many Linux distribution repositories, so installing it using the system package manager is recommended. For example, on Debian/Ubuntu: sudo apt install gcc-arm-linux-gnueabihf
This installs the compiler targeting the ARM EABI hf architecture, compatible with most modern 32-bit and 64-bit ARM boards. Other targets like arm-linux-gnueabi for older ARMv4t are also available.
For manual installation, the cross compiler and sysroot can be downloaded from ARM’s website or built from source. Extract the archive and add the bin directory to the PATH to access the compiler tools.
To compile a simple C program called main.c for ARM: arm-linux-gnueabihf-gcc -o main main.c
This invokes the cross compiler arm-linux-gnueabihf-gcc which generates an ARM executable called main. The same familiar GCC options and arguments can be used for things like specifying optimization level and debug info.
By default, the compiler generates code for the ARM instruction set supported by the target architecture. For 32-bit ARM, add -marm and for 64-bit ARM use -mabi=lp64. The -mfpu, -mcpu and -march options control the floating point, CPU and architecture version.
Like gcc, the linker needs to target ARM so arm-linux-gnueabihf-gcc should be used for linking as well. The location of libraries and header files for cross compiling is specified by the sysroot which points to the root file system for the target.
For example, to link an executable called app using libarm.so: arm-linux-gnueabihf-gcc main.o libarm.so -o app
The compiler searches the sysroot for the required libraries. The location of sysroot can be configured on most Linux distributions in /etc/ld.so.conf.d/arm-linux-gnueabihf.conf.
Sysroot and Toolchain
The sysroot contains C libraries, headers and other files that mimic the root file system of the ARM target. This allows the cross compiler to find the necessary files to build binaries that will run on the target.
Some key folders include:
- /lib – target system libraries
- /usr/include – target headers
- /usr/lib – additional target libraries
Besides the compiler, the gcc-arm toolchain also includes other binary utilities like the linker, assembler, archiver and debugger. These tools are prefixed with the target prefix like arm-linux-gnueabihf.
Some common tools include:
- arm-linux-gnueabihf-g++ – C++ compiler
- arm-linux-gnueabihf-as – Assembler
- arm-linux-gnueabihf-ld – Linker
- arm-linux-gnueabihf-gdb – Debugger
- arm-linux-gnueabihf-objdump – Object file analyzer
Many aspects of the gcc-arm toolchain and the way it builds code for the target can be customized using command line options. Some options include:
- -mcpu – Target ARM processor for optimizations.
- -march – Target ARM architecture version.
- -mfpu – Floating point hardware configuration.
- -mabi – ABI compliance for the target OS.
- -marm / -mthumb – ARM or Thumb instruction sets.
- -mfloat-abi – Floating point ABI convention.
Tuned libraries for specific ARM CPUs can also be selected using options like -mtune=cortex-a72. The ARM toolchain and sysroot needs to be compatible with the target board and OS for the resulting binaries to function correctly.
The gcc-arm cross toolchain is commonly integrated into automated build systems and IDEs to streamline embedded development workflows. Some options include:
- CMake – Cross compile using toolchain files.
- Makefiles – Invoke with arm-linux-gnueabihf-gcc.
- Docker – Build ARM container images.
- Jenkins – Cross compile in pipelines.
Scripting is used to execute the cross compiler and tools instead of the native toolchain. This allows automation of building, testing and deployment across desktop development and ARM/embedded target platforms.
Debugging cross compiled ARM binaries requires using the gdb cross debugger in the toolchain like arm-linux-gnueabihf-gdb. It connects to a remote ARM target over a JTAG or SWD debugger probe.
Some common approaches include:
- Debugging on device by running gdbserver.
- Using an external hardware debugger like J-Link or ST-Link.
- Debugging in an emulator like QEMU.
The debugger needs to be properly configured to match the target and usable .debug debug symbols must be generated during ARM compilation for full debugging. Enabling gdb debugging improves productivity when working with gcc-arm cross toolchains.
The gcc-arm cross compiler is a key toolchain component for building and debugging ARM applications on Linux desktops and servers. Using gcc-arm allows taking advantage of fast x86 hardware while targeting code for ARM Cortex-M, Cortex-R and Cortex-A cores using a unified GNU compiler toolchain.