-
-
Notifications
You must be signed in to change notification settings - Fork 102
Cross Compiler CMake Usage Guide with Raspbian 32 bit Image
This guide documents the complete steps to create rootfs/sysroot so that you can create a cross compile environment for any Raspberry Pi on a Linux machine using only a Raspberry OS OS 32-bit image file. After that we will cross-compile a working Software Binaries (Hello-World CMAKE example in this case) with CMAKE using only the Raspberry Pi GCC Toolchains available within our project.
Note
- This guide is suitable if you don't own any Raspberry Pi hardware yet.
- Our Cross-Compiler toolchains also works out-of-the-box on any Linux distro via WSL2 on Windows 10 Machines. 💯
Warning
- These instruction are only meant for 32-bit Raspberry OS OS images only.
- The Stretch (Debian Version 9) 32-bit/64-bit toolchains are no longer supported!
- Any x86/x86_64 AMD/Intel machine
- Host: Any Linux machine (💡 Our Cross-Compiler toolchains also works out-of-the-box on any Linux distro via WSL2 on Windows 10 Machines. 💯)
- Target: Any Raspberry Pi 32-bit Buster (Debian 10) and above OS image (Raspberry Pi OS Bookworm Image Tested)
- A cup of coffee ☕.
Let's go through all the commands for our Host Machine, i.e. PC/Laptop, where you going to build sysroot and cross-compile software binaries (Hello world application in this case) for your Raspberry Pi.
First of all, Run the following commands to update your system and install important dependancies:
sudo apt update
sudo apt dist-upgrade
sudo apt install build-essential cmake unzip gfortran xz-utils
sudo apt install gcc git bison python gperf pkg-config gdb-multiarch wget rsync libgmp-dev libmpfr-dev
sudo apt install g++ gperf flex texinfo gawk bison openssl pigz libncurses-dev autoconf automake tar figlet
You can use these following commands to create "cmake-test" to use as workspace for the project:
sudo mkdir ~/cmake-test
sudo mkdir ~/cmake-test/tools
sudo mkdir ~/cmake-test/build
sudo chown -R 1000:1000 ~/cmake-test
cd ~/cmake-test
Important
Ensure the last command should have changed your current directory to ~/cmake-test
. If not, run the last line again to make sure you are inside it, as the next steps assume you're running your commands from this directory.
First, make sure you're in cmake-test folder as needed for the next sections:
cd ~/cmake-test
Warning
You need active internet connection to update packages while building images.
git clone https://github.com/abhiTronix/rpi_rootfs.git && cd rpi_rootfs
Always use the latest image for build Sysroot. Download latest Raspberry OS-lite compressed images from here
Tip
These instruction also work for 32-bit Buster and Bullseye Raspberry OS images.
# download compressed image
https://downloads.raspberrypi.com/raspios_lite_armhf/images/raspios_lite_armhf-2024-07-04/2024-07-04-raspios-bookworm-armhf-lite.img.xz
# extract it
unxz 2024-07-04-raspios-bookworm-armhf-lite.img.xz
Important
Use ./build_rootfs.sh clean
if anything goes wrong.
sudo chmod +x ./build_rootfs.sh
# To build rootfs
./build_rootfs.sh create ./2024-07-04-raspios-bookworm-armhf-lite.img
If you have followed above instructions carefully then, built rootfs will exist in ~/cmake-test/rpi_rootfs/rootfs
directory.
Caution
DO NOT move or copy rootfs
directory to somewhere else otherwise rootfs files will throw errors.
Now, Let's first change into tools
directory for downloading our Precompiled Cross-compiler with the following command:
cd ~/cmake-test/tools
Note
Ensure the last command should have changed your current directory to ~/cmake-test/tools
now. If not, run it again.
Copy URL from one of following Precompiled Compressed Base (or Pre-installed) Toolchain version (for maximum compatibility) based on your Raspberry Pi Variant and OS you installed on it from below:
Warning
The Stretch (Debian Version 9) 32-bit/64-bit toolchains are no longer supported!
Raspberry Pi Board | Buster 32-bit OS (Debian Version 10) | Bullseye 32-bit OS (Debian Version 11) | Bookworm 32-bit OS (Debian Version 12) |
---|---|---|---|
Raspberry Pi - Zero W/WH/2W & 1 Model A/B/A+/B+ | 8.3.0 | 10.2.0 | 12.2.0 |
Raspberry Pi - 2/3 Model A/B | 8.3.0 | 10.2.0 | 12.2.0 |
Raspberry Pi - 3 Model A+/B+ & 4 Model 400/B & 5 & Compute 3/3-lite/3+/4/4S | 8.3.0 | 10.2.0 | 12.2.0 |
Tip
You can also use the latest cross-compiler binaries instead. But they are not tested or recommended.
After that, paste your copied URL and run the following command to download the Cross-compiler:
wget <Copied Binary URL goes here> #for e.g. => wget https://sourceforge.net/projects/raspberry-pi-cross-compilers/files/Raspberry%20Pi%20GCC%20Cross-Compiler%20Toolchains/Bookworm/GCC%2012.2.0/Raspberry%20Pi%202%2C%203/cross-gcc-12.2.0-pi_2-3.tar.gz
Once it is downloaded, we can extract it using the following command:
tar xf cross-gcc-*.tar.gz
First, let's move back into the cmake-test folder as needed for the next sections:
cd ~/cmake-test
Now we need to create suitable files for our CMAKE project.
Let's try to compile and run a C++17 code that uses an if block with init-statement (the example is a bit simple, but will show you how to compile C++17 programs):
#include <iostream>
int main() {
// if block with init-statement:
if (int a = 5; a < 8) {
std::cout << "Local variable a is < 8\n";
} else {
std::cout << "Local variable a is >= 8\n";
}
return 0;
}
Let's create a typical cross-compiling toolchain that has content such as:
Warning
Remember to replace Cross-Compiler Toolchain absolute path with yours in following CMAKE file.
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(tools <absolute path to toolchain. for e.g $ENV{HOME}/cmake-test/tools/cross-pi-gcc-12.2.0-0>) # warning change toolchain path here.
set(rootfs_dir $ENV{HOME}/cmake-test/rpi_rootfs/rootfs) # warning make sure rootfs exist at this path
set(CMAKE_FIND_ROOT_PATH ${rootfs_dir})
set(CMAKE_SYSROOT ${rootfs_dir})
set(CMAKE_LIBRARY_ARCHITECTURE arm-linux-gnueabihf)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
## Compiler Binary
SET(BIN_PREFIX ${tools}/bin/arm-linux-gnueabihf)
SET (CMAKE_C_COMPILER ${BIN_PREFIX}-gcc)
SET (CMAKE_CXX_COMPILER ${BIN_PREFIX}-g++ )
SET (CMAKE_LINKER ${BIN_PREFIX}-ld
CACHE STRING "Set the cross-compiler tool LD" FORCE)
SET (CMAKE_AR ${BIN_PREFIX}-ar
CACHE STRING "Set the cross-compiler tool AR" FORCE)
SET (CMAKE_NM {BIN_PREFIX}-nm
CACHE STRING "Set the cross-compiler tool NM" FORCE)
SET (CMAKE_OBJCOPY ${BIN_PREFIX}-objcopy
CACHE STRING "Set the cross-compiler tool OBJCOPY" FORCE)
SET (CMAKE_OBJDUMP ${BIN_PREFIX}-objdump
CACHE STRING "Set the cross-compiler tool OBJDUMP" FORCE)
SET (CMAKE_RANLIB ${BIN_PREFIX}-ranlib
CACHE STRING "Set the cross-compiler tool RANLIB" FORCE)
SET (CMAKE_STRIP {BIN_PREFIX}-strip
CACHE STRING "Set the cross-compiler tool RANLIB" FORCE)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Finally create a suitable CMakeLists.txt file:
cmake_minimum_required(VERSION 3.10)
project(cmake_test)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)
add_executable(cmake_test main.cpp)
Let's move into the build directory for further steps, as we don't want to build within that source directory as its crowded, so we will access it from within this this directory:
cd ~/cmake-test/build
Caution
Ensure you are still in the ~/cmake-test/build
directory.
Finally, Now we can configure our Hello-World CMAKE Project as follows:
cmake -DCMAKE_TOOLCHAIN_FILE=~/cmake-test/PI.cmake -DCMAKE_BUILD_TYPE=Debug ..
Our build has been configured now, and it is time to actually build the source files, and run the following command:
make -j$(nproc)
Note
The -j$(nproc)
option indicates that the job should be spread into mutliple threads and run in parallel on available cores.
and your compiled files will be available at ~/cmake-test/build
.
If these binaries helped you big time, please consider supporting it. Thank you.
Also, don't forget to share your views & drop a ⭐
- Native-Compiler ARM Toolchains Guide
- Cross-Compiler ARM Toolchains Guide
- Native-Compiler 64-Bit GCC ARM64 Toolchains Guide
- Cross-Compiler 64-Bit GCC ARM64 Toolchains Guide