-
-
Notifications
You must be signed in to change notification settings - Fork 107
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 Raspbian 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.
👀 This guide is suitable if you don't own a Raspberry Pi hardware yet. |
---|
💡 Note: Our Cross-Compiler toolchains also works out-of-the-box on any Linux distro via WSL2 on Windows 10 Machines. 💯 |
---|
- 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 Raspbian 32-bit OS image (Raspbian Buster lite 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
sudo apt install gcc git bison python gperf pkg-config gdb-multiarch wget qemu-user-static rsync
sudo apt install gcc 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
Note: 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
git clone https://github.com/abhiTronix/rpi_rootfs.git && cd rpi_rootfs
💡 Note: These instruction also work for 32-bit Stretch and Bullseye images.
💡 Note: Always use the latest image for build sysroot. Download latest Raspbian-lite images from here
curl -O https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-03-25/2021-03-04-raspios-buster-armhf-lite.zip
unzip 2021-03-04-raspios-buster-armhf-lite.zip
💡 Note: These instruction also work for 32-bit Stretch images.
💡 Tip: Use ./build_rootfs.sh clean
if anything goes wrong.
sudo chmod +x ./build_rootfs.sh
# To build rootfs
./build_rootfs.sh create ./2021-03-04-raspios-buster-armhf-lite.img
If you have followed above instructions carefully then, built rootfs will exist in ~/cmake-test/rpi_rootfs/rootfs
directory.
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-Toolchain (for maximum compatibility) based on your Raspberry Pi Variant and OS you installed on it, from below:
Raspberry Pi Board | Stretch(32-bit) OS | Buster(32-bit) OS | Bullseye(32-bit) OS |
---|---|---|---|
Raspberry Pi - Zero/W/WH & 1 Model A/B/A+/B+ | 6.3.0 | 8.3.0 | 10.2.0 |
Raspberry Pi - 2 & 3 Model A/B | 6.3.0 | 8.3.0 | 10.2.0 |
Raspberry Pi - 3 & 4 Model A+/B+ & Compute 3/3-lite/3+ | 6.3.0 | 8.3.0 | 10.2.0 |
Note: You can also use the latest cross-compiler binaries instead. But they are not tested.
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/Buster/GCC%208.3.0/Raspberry%20Pi%202%2C%203/cross-gcc-8.3.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:
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-8.3.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
Important: 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: -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