How to Fix Cross Compiling for Raspberry Pi 3 on Linux Error with Boost

I ran into a really frustrating problem while trying to cross compile an application for my Raspberry Pi 3. I didn’t want to keep the Pi compiling all day, so I set up a cross-compilation toolchain on my PC. Everything seemed fine until I tried to build a project that depended on Boost. Suddenly, CMake exploded with a Boost error. Let me walk you through what I saw, what it actually means, how I fixed it, and how I tested my setup with a little practice project.

My First Toolchain File

Here’s the toolchain file I started with:

# Toolchain-Raspberry-pi.cmake (original)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)

set(CMAKE_C_COMPILER $ENV{HOME}/Code/toolchains/crosscompile-raspberrypi/bin/arm-unknown-linux-androideabi-gcc)
set(CMAKE_CXX_COMPILER $ENV{HOME}/Code/toolchains/crosscompile-raspberrypi/bin/arm-unknown-linux-androideabi-g++)

set(CMAKE_FIND_ROOT_PATH $ENV{HOME}/Code/toolchains/crosscompile-raspberrypi/)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

The Error I Saw

When I ran CMake with that toolchain, I got this:

Found package configuration file:
/usr/lib/cmake/boost_system-1.71.0/boost_system-config.cmake
but it set boost_system_FOUND to FALSE …

No suitable build variant has been found.
Tried and rejected:
* libboost_system.so.1.71.0 (64 bit, need 32)
* libboost_system.a (64 bit, need 32)

What This Error Really Means

At first glance it looks like CMake just can’t find Boost. But here’s the truth:

  • CMake did find Boost but on my PC, under /usr/lib. Those are 64-bit x86 libraries.
  • My Raspberry Pi 3 runs 32-bit ARM (armv7, hard float). CMake realized that and rejected the host libs.
  • To make matters worse, I was pointing my toolchain at arm-unknown-linux-androideabi-gcc, which is an Android toolchain, not Raspberry Pi OS.
  • Installing lib32-boost-libs on my PC didn’t help, because that’s 32-bit x86, not ARM.

So the bottom line: I had an architecture mismatch, a wrong compiler triple, and no sysroot with ARM Boost libraries.

The Fix

Here’s how I solved it step by step.

Install the right cross compiler

I switched to a real Linux ARM cross compiler:

sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

Create a Raspberry Pi sysroot

On the Pi I installed Boost development headers and libs:

sudo apt update
sudo apt install build-essential libboost-all-dev

Then I synced the Pi’s libraries and headers to my PC:

mkdir -p $HOME/rpi-sysroot
rsync -avz --delete --rsync-path="sudo rsync" \
  pi@raspberrypi.local:/lib/  $HOME/rpi-sysroot/lib/
rsync -avz --delete --rsync-path="sudo rsync" \
  pi@raspberrypi.local:/usr/  $HOME/rpi-sysroot/usr/

A Corrected Toolchain File

Here’s the fixed toolchain:

# Toolchain-RaspberryPi-gnueabihf.cmake (fixed)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(TOOLCHAIN_PREFIX arm-linux-gnueabihf)
set(CMAKE_C_COMPILER   ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)

set(CMAKE_SYSROOT "$ENV{HOME}/rpi-sysroot")

set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard")

set(ENV{PKG_CONFIG_SYSROOT_DIR} "${CMAKE_SYSROOT}")
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/arm-linux-gnueabihf/pkgconfig:${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")

Minimal Project CMakeLists

cmake_minimum_required(VERSION 3.15)
project(RpiBoostDemo LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)

set(Boost_NO_SYSTEM_PATHS ON)
set(BOOST_ROOT       "$ENV{HOME}/rpi-sysroot/usr")
set(BOOST_INCLUDEDIR "$ENV{HOME}/rpi-sysroot/usr/include")
set(BOOST_LIBRARYDIR "$ENV{HOME}/rpi-sysroot/usr/lib/arm-linux-gnueabihf")

find_package(Boost 1.67 REQUIRED COMPONENTS filesystem system)

add_executable(demo src/main.cpp)
target_link_libraries(demo PRIVATE Boost::filesystem Boost::system)

Build Command

mkdir -p build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=$HOME/Code/toolchains/cmake-files/raspberry-pi/Toolchain-RaspberryPi-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build . -j

Now CMake happily finds Boost in the sysroot and builds the project.

Practice Functionality

I didn’t want to stop there. I wrote a small test app to prove the cross-compiled Boost libs were actually working.

Filesystem Lister

src/main.cpp

#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <iostream>

int main(int argc, char** argv) {
    namespace fs = boost::filesystem;
    fs::path p = (argc > 1) ? fs::path(argv[1]) : fs::current_path();

    boost::system::error_code ec;
    if (!fs::exists(p, ec)) {
        std::cerr << "Path does not exist: " << p.string()
                  << " (error: " << ec.message() << ")\n";
        return 1;
    }

    if (fs::is_directory(p, ec)) {
        std::cout << "Listing directory: " << p.string() << "\n";
        for (auto& entry : fs::directory_iterator(p, ec)) {
            std::cout << " - " << entry.path().filename().string() << "\n";
        }
    } else {
        auto size = fs::file_size(p, ec);
        std::cout << "File: " << p.string() << " | size=" << size << " bytes\n";
    }
    return 0;
}

On the Pi I ran:

./demo /home/pi

And it listed my files correctly.

Add a Timer with Boost.Asio

I then extended the program with a one-second timer:

#include <boost/asio.hpp>

// inside main()
boost::asio::io_context io;
boost::asio::steady_timer t(io, std::chrono::seconds(1));
t.async_wait([](const boost::system::error_code& ec){
    if (!ec) std::cout << "Timer fired after 1s (Boost.Asio test)\n";
});
io.run();

This proved not only Boost.Filesystem worked, but also Boost.System + Boost.Asio.

Final Thought

At first, I thought the Boost error was something trivial. But the real issue was bigger: I was mixing host libraries with a target architecture, using the wrong compiler triple, and not providing a proper sysroot. Once I fixed those three things, cross compiling Boost-based projects for Raspberry Pi 3 became straightforward.

Related blog posts