CMake Cross Compilation for ARM Architecture

I use CMake to write computer programs in C/C++.  This is a great cross-platform build utility that makes it very easy to compile small and large programs on most operating systems.  Moreover, packages and source code for installation are readily available on the CMake website.  When using CMake on Windows, I like to download the installer, but when I use CMake on Linux, I usually bootstrap, compile and install CMake from source to obtain the most up-to-date binary.

I work with embedded systems that are mostly ARM architecture, and I often use Windows for engineering software, so cross-compilation via Windows is a common task.  I like to use CMake to perform the cross-compilation since it is fast, easy-to-use, and the syntax is very efficient.  However, cross-compilation for ARM is not always an easy task since the compiler settings need to be properly provided.

There are two ways to proceed, depending on whether the ARM embedded system is "baremetal" (without an OS) or whether an OS is used (such as Linux).  For any embedded system, the compiler needs to be the correct version and the correct architecture for both the host and the target machine.

Baremetal

The compiler is downloaded from ARM and has the gcc-arm-none-eabi prefix indicating that an OS is not being used.  The compiler is downloaded, installed (using the installer or just by copying) and the bin directory is added to the system PATH.

Assuming in CMake that we have a device project (the name can be changed accordingly), we need to set the cross-compiler and the architecture.

set(CMAKE_SYSTEM_NAME Generic)
cmake_minimum_required(VERSION 3.21)
project(device)
set(CMAKE_CXX_STANDARD 17)

set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
add_compile_options(-march=armv7-a --specs=nosys.specs)
add_link_options(-march=armv7-a --specs=nosys.specs)

add_executable(device
main.cpp)

The system name needs to be initially set as Generic to ensure that there are no linking errors.  In addition, the architecture needs to be set as required (-march=armv7-a).  Also, the cross-compiler is not using a system specifications file, so the specs are set accordingly for both the compiler and linker options (--specs=nosys.specs).

Linux

 Here the compiler can be downloaded from ARM and has the word linux somewhere in the description of the toolchain.  Many ARM processors are 32-bit, but there are some that are 64-bit and you need to download the version of the toolchain that works for a specific processor.  Here as an example, arm-none-linux-gnueabihf is downloaded and the bin directory is added to the system PATH.  On Linux, the tar.xz file can be unzipped using available tools (command-line or GUI), whereas on Windows the 7-Zip software can be used.

There are some (small) differences compared to the code above: a system specifications file is not required, and the names of the compilers need to be changed accordingly.  The architecture should still be set.

set(CMAKE_SYSTEM_NAME Generic)
cmake_minimum_required(VERSION 3.21)
project(device)
set(CMAKE_CXX_STANDARD 17)

set(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++)
add_compile_options(-march=armv7-a)
add_link_options(-march=armv7-a)

add_executable(device
main.cpp)

After the build, the program can be transferred to the embedded system using SSH and run as required.  A screenshot of the Hello World program running on the device is obligatory and is provided above.

This article was updated on March 17, 2022

Dr. Nicholas J. Kinar

Dr. Nicholas J. Kinar is a hydrologist and researcher at the University of Saskatchewan. This is a blog of ideas, techniques and things that Nicholas perceives as unsophisticated knowledge in the Homeland of the Métis / Treaty 6 Territory / Saskatoon, Saskatchewan, Canada / Earth. His full name is Nicholas John Stanislaus Kinar. This blog of unsophisticated knowledge is intended to document some information that Nicholas finds useful. However, he does not mind if other people might find this information to be useful as well.