Skip to main content

RPI4 Cross Compile for libcamera-app on Mac Pro (with docker) (4): Build libcamera-apps

 

RPI4 Cross Compile for libcamera-app on Mac Pro (with docker) (4): Build libcamera-apps

Why am I doing this

After reading the camera app instructions, I thought of starting the development by modifying the libcamera-apps. Therefore, the first step is to build the original repo; after that, I can add my stuff to the official standard version.

It looks easy. The code-building instructions are well-documented on the official website, but there is a catch in my mind. I bought an expensive, neat, and tidy Macbook Pro after quitting my job as a mind-comforting geek gadget to compensate for losing my working life, so I don't want to build the code on a small RPI board. Instead, I want to build the code and develop things on my new laptop, which is why I got into this over tons of unexpected things just popping up in my sight…

Preface

  1. Create a docker container where I can cross-compile the libcamera-apps.
    1. Setup chroot
    2. Setup toolchain
    3. Build libcamera-apps <-
  2. The docker container should include the development environment I like.
    1. Setup vim
  3. Develop and debug for the self-built libcamera-apps
  4. My GitHub repository

Goals for building libcamera-apps

  • Docker container for cross-compiling
  • Cmake test
  • Meson test
  • Libcamera example
  • Build libcamera-apps
From the previous pages [Setup chroot] and [Setup toolchain], we got a docker image with a workable sysroot for bullseye-arm64 and a docker volume, rpi-toolchain, containing the toolchain that has multiple tools for building code for the RPI4 board. Thus, we should test the setup by building codes and running on the RPI4 board.

Docker container for cross-compiling

First, let’s start a container by using the below command.

#!/bin/bash
_source=$SOURCE_CODE_DIR
_docker_source=/root/main
_test_source=$SOURCE_CODE_EXTRA_DATA_DIR
_docker_test_source=/root/test_data

_docker_image=aarch64-rpi4-bullseye-cross-compiler-2204:v0.1.3
_docker_volume=docker_build_rpi
_docker_volume_toolchain=rpi4-toolchain
_docker_volume_crosstool_ng=crosstoll_ng

docker run -it --rm \\\\
           --privileged=true \\\\
           --cap-add=SYS_ADMIN --security-opt apparmor:unconfined \\\\
           -v $_docker_volume:/root/build \\\\
           -v $_docker_volume_toolchain:/opt \\\\
           -v $_docker_volume_crosstool_ng:/root/crosstool_ng \\\\
           -v $_source:$_docker_source:delegated \\\\
           -v $_test_source:$_docker_test_source:delegated \\\\
           --net=host \\\\
           $_docker_image bash

The below diagram shows the important components of the system configuration:

  • sysroot: the location of our sysroot is in /root/sys/chroots/rpi-bullseye-arm64 where we can download packages we want by using sbuild-apt rpi-$RELEASE-$ARCH apt-get install $packages-to-be-downloaded
  • toolchain: we have built and stored the toolchain in the volume: rpi-toolchain, so we don’t rebuild the toolchain every time we start the container, and we can easily change the toolchain by binding the volumes stored by different toolchains to /opt
  • source code: binding a directory outside the docker container, and I can put the project that needs to be cross-compiled in this directory.

CMake test

After the container is well set, we can try a simple example, which is the same example in the post [Earthly, A. Bhattacharyea], where the code needs the libgmp to work properly and libgmp comes from the apt package, libgmp-dev, so if we can build and run the binary on the PRI4, then it proves that we can write codes that use the library from http://deb.debian.org/debian.

  • Follow the instructions in [Earthly, A. Bhattacharyea] from the section: “Writing the Program and Setting Up CMake,” but change the content of aarch64-rpi4-linux-gnu.cmake as the below lines.

    # <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html>
     
    # Cross-compilation system information
    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR arm)
    
    # The sysroot contains all the libraries we might need to link against and
    # possibly headers we need for compilation
    set(CMAKE_SYSROOT /root/sys/chroots/rpi-bullseye-arm64/)
    set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
    set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)
    set(CMAKE_STAGING_PREFIX $ENV{HOME}/RPi-dev/staging-armv8-rpi4)
    
    # Set the compilers for C, C++ and Fortran
    set(RPI_GCC_TRIPLE "aarch64-rpi4-linux-gnu")
    set(CMAKE_C_COMPILER ${RPI_GCC_TRIPLE}-gcc CACHE FILEPATH "C compiler")
    set(CMAKE_CXX_COMPILER ${RPI_GCC_TRIPLE}-g++ CACHE FILEPATH "C++ compiler")
    
    # Don't look for programs in the sysroot (these are ARM programs, they won't run
    # on the build machine)
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    # Only look for libraries, headers and packages in the sysroot, don't look on
    # the build machine
    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(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64)
    
  • Install libgmp-dev

    sbuild-apt rpi-$RELEASE-$ARCH apt-get install libgmp-dev
    
  • Cross-compile

    • Note: TC=aarch64-rpi4-linux-gnu
    cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/$TC.cmake
    cmake --build build -j
    cmake --install build
    
    • The installed binary is $ENV{HOME}/RPi-dev/staging-armv8-rpi4/bin/fact
  • Test the binary

    • copy fact into RPI4 and run, and the output is identical to the output in [Earthly, A. Bhattacharyea] , which means we successfully cross-compiled a binary using cmake.
    pi@raspberrypi:~ $ ./fact-cross-demo-1025
    The factorial of 1000 = 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

 

Meson test

Before I saw the meson script in libcamera-app project, I haven’t heard of meson so I need a simple test before building libcamera-apps to adjust the config and prove I can cross-compile by meson. Therefore, I looked into the projects using the meson page and chose the first project 2048.cpp as the simple example. To cross-compile in meson, I needed to write a “cross file” and set the file as one of the setup arguments. The cross-file-related documents are [meson cross compilation] and [meson cross and native file reference]. They helped me to write my own file as the below example:

  • rpi_cross_file.txt

    [constants]
    toolchain_dir = '/opt/x-tools/aarch64-rpi4-linux-gnu/bin/'
    target_setting = 'aarch64-rpi4-linux-gnu'
    c_sys_root = '/root/sys/chroots/rpi-bullseye-arm64/'
    [binaries]
    c = toolchain_dir / target_setting + '-gcc'
    cpp = toolchain_dir / target_setting + '-g++'
    strip = toolchain_dir / target_setting + 'strip'
    pkg-config = '/usr/bin/pkg-config'
    [properties]
    sys_root = c_sys_root
    pkg_config_libdir = sys_root + 'usr/lib/aarch64-linux-gnu/pkgconfig'
    [host_machine]
    system = 'Linux'
    cpu_family = 'aarch64'
    cpu = 'aarch64'
    endian = 'little'
    
  • Build 2048.cpp

    git clone <https://github.com/plibither8/2048.cpp.git>
    cd 2048.cpp
    meson setup --cross-file rpi_cross_file.txt build
    meson compile -C build
    meson configure build --prefix=$(pwd)/installed_bin
    meson install -C build
    
  • Test on RPI

    • copy 2048.cpp/installed_bin/bin/2048 to RPI4 and run
      • It worked, too.
    /\\\\\\\\\\\\\\\\\\          /\\\\\\\\\\\\\\                /\\\\\\         /\\\\\\\\\\\\\\\\\\
      /\\\\\\///////\\\\\\      /\\\\\\/////\\\\\\            /\\\\\\\\\\       /\\\\\\///////\\\\\\
      \\///      \\//\\\\\\    /\\\\\\    \\//\\\\\\         /\\\\\\/\\\\\\      \\/\\\\\\     \\/\\\\\\
                 /\\\\\\/    \\/\\\\\\     \\/\\\\\\       /\\\\\\/\\/\\\\\\      \\///\\\\\\\\\\\\\\\\\\/
               /\\\\\\//      \\/\\\\\\     \\/\\\\\\     /\\\\\\/  \\/\\\\\\       /\\\\\\///////\\\\\\
             /\\\\\\//         \\/\\\\\\     \\/\\\\\\   /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\   /\\\\\\      \\//\\\\\\
            /\\\\\\/            \\//\\\\\\    /\\\\\\   \\///////////\\\\\\//   \\//\\\\\\      /\\\\\\
            /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\   \\///\\\\\\\\\\\\\\/              \\/\\\\\\      \\///\\\\\\\\\\\\\\\\\\/
            \\///////////////      \\///////                \\///         \\/////////
    
      ┌───────────────────────────┐
      │ SCORE:                  0 │
      │ BEST SCORE:             0 │
      │ MOVES:                  1 │
      └───────────────────────────┘
    
      ┌──────┬──────┬──────┬──────┐
      │      │      │      │      │
      ├──────┼──────┼──────┼──────┤
      │      │      │      │    2 │
      ├──────┼──────┼──────┼──────┤
      │      │    2 │      │      │
      ├──────┼──────┼──────┼──────┤
      │      │      │      │    2 │
      └──────┴──────┴──────┴──────┘
    
      W or K or ↑ => Up
      A or H or ← => Left
      S or J or ↓ => Down
      D or L or → => Right
      Z or P => Save
    
      Press the keys to start and continue.
    

Libcamera example

And next, I want to test building the code from [libcamera/simple-cam.git], which is the official example of the libcamera usage, so if it worked, we probably have little problem to our final goal: cross-compiling libcamera-app

  • Download the required packages

    sbuild-apt rpi-$RELEASE-$ARCH apt-get update
    sbuild-apt rpi-$RELEASE-$ARCH apt-get install libcamera-dev
    sbuild-apt rpi-$RELEASE-$ARCH apt-get install libevent-dev
    
  • Download simple-cam

    git clone https://git.libcamera.org/libcamera/simple-cam.git
    
  • Meson build setup

    cd simple-cam
    meson setup --cross-file rpi_cross_file.txt build
    
    • And, failed.
    meson.build:16:0: ERROR: Pkg-config binary for machine 1 not found. Giving up.
    
    • I found that the meson --verson In my container is 0.61.2, and it seems to have issues when using pkg-config, so I downloaded the latest meson on GitHub and used it by:
    git clone <https://github.com/mesonbuild/meson.git>
    cd simple-cam
    ../meson/meson.py setup --wipe --cross-file rpi_cross_file.txt build
    ../meson/meson.py compile -C build
    
    • And, failed again…
    /opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-g++ -Isimple-cam.p -I. -I.. -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libcamera -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c++17 -O0 -g -Wno-unused-parameter -pthread -MD -MQ simple-cam.p/event_loop.cpp.o -MF simple-cam.p/event_loop.cpp.o.d -o simple-cam.p/event_loop.cpp.o -c ../event_loop.cpp
    ../event_loop.cpp:11:10: fatal error: event2/event.h: No such file or directory
       11 | #include <event2/event.h>
          |          ^~~~~~~~~~~~~~~~
    
    • So, I add cpp_args in rpi_cross_file.txts.
    [constants]
    toolchain_dir = '/opt/x-tools/aarch64-rpi4-linux-gnu/bin/'
    target_setting = 'aarch64-rpi4-linux-gnu'
    c_sys_root = '/root/sys/chroots/rpi-bullseye-arm64/'
    [binaries]
    c = toolchain_dir / target_setting + '-gcc'
    cpp = toolchain_dir / target_setting + '-g++'
    strip = toolchain_dir / target_setting + 'strip'
    pkg-config = '/usr/bin/pkg-config'
    [properties]
    sys_root = c_sys_root
    pkg_config_libdir = sys_root + 'usr/lib/aarch64-linux-gnu/pkgconfig'
    [built-in options]
    cpp_args = ['-I' + c_sys_root + 'usr/include/','-I' + c_sys_root + 'usr/include/aarch64-linux-gnu/']
    [host_machine]
    system = 'Linux'
    cpu_family = 'aarch64'
    cpu = 'aarch64'
    endian = 'little'
    
    • And it passed the including part but failed at the linking stage, so the cpp_link_args should be specified, too
    /opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-g++  -o simple-cam simple-cam.p/simple-cam.cpp.o simple-cam.p/event_loop.cpp.o -Wl,--as-needed -Wl,--no-undefined -Wl,-rpath,/root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu -Wl,-rpath-link,/root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu -Wl,--start-group /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libcamera.so /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libcamera-base.so /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libevent_pthreads.so /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libevent.so -Wl,--end-group -pthread
    /opt/x-tools/aarch64-rpi4-linux-gnu/bin/../lib/gcc/aarch64-rpi4-linux-gnu/10.5.0/../../../../aarch64-rpi4-linux-gnu/bin/ld: warning: libz.so.1, needed by /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libdw.so.1, not found (try using -rpath or -rpath-link)
    /opt/x-tools/aarch64-rpi4-linux-gnu/bin/../lib/gcc/aarch64-rpi4-linux-gnu/10.5.0/../../../../aarch64-rpi4-linux-gnu/bin/ld: warning: liblzma.so.5, needed by /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libdw.so.1, not found (try using -rpath or -rpath-link)
    /opt/x-tools/aarch64-rpi4-linux-gnu/bin/../lib/gcc/aarch64-rpi4-linux-gnu/10.5.0/../../../../aarch64-rpi4-linux-gnu/bin/ld: warning: libbz2.so.1.0, needed by /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/libdw.so.1, not found (try using -rpath or -rpath-link)
    ...
    reference to `lzma_index_uncompressed_size@XZ_5.0'
    collect2: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.
    
    • Specify the cpp_link_args
      • Note: the added location is found by find command for the missed libraries.
    [constants]
    toolchain_dir = '/opt/x-tools/aarch64-rpi4-linux-gnu/bin/'
    target_setting = 'aarch64-rpi4-linux-gnu'
    c_sys_root = '/root/sys/chroots/rpi-bullseye-arm64/'
    [binaries]
    c = toolchain_dir / target_setting + '-gcc'
    cpp = toolchain_dir / target_setting + '-g++'
    strip = toolchain_dir / target_setting + 'strip'
    pkg-config = '/usr/bin/pkg-config'
    [properties]
    sys_root = c_sys_root
    pkg_config_libdir = sys_root + 'usr/lib/aarch64-linux-gnu/pkgconfig'
    [built-in options]
    cpp_args = ['-I' + c_sys_root + 'usr/include/','-I' + c_sys_root + 'usr/include/aarch64-linux-gnu/']
    cpp_link_args = ['-Wl,-rpath,' + c_sys_root + 'lib/aarch64-linux-gnu/', '-Wl,-rpath-link,' + c_sys_root + 'lib/aarch64-linux-gnu/']
    [host_machine]
    system = 'Linux'
    cpu_family = 'aarch64'
    cpu = 'aarch64'
    endian = 'little'
    
  • Test the binary on RPI4 board, and it is workable.

    pi@raspberrypi:~ $ ./simple-pi-cross-test-1025
    [4:04:07.691820562] [2377]  INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
    [4:04:07.756722838] [2378]  WARN RPI vc4.cpp:383 Mismatch between Unicam and CamHelper for embedded data usage!
    [4:04:07.757532325] [2378]  INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media4 and ISP device /dev/media0
     -  'imx219' (/base/soc/i2c0mux/i2c@1/imx219@10)
    Default viewfinder configuration is: 800x600-NV12
    Validated viewfinder configuration is: 800x600-NV12
    [4:04:07.758383719] [2377]  INFO Camera camera.cpp:1033 configuring streams: (0) 800x600-NV12
    [4:04:07.758904193] [2378]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1640x1232-SBGGR10_1X10 - Selected unicam format: 1640x1232-pBAA
    Allocated 4 buffers for stream
    
    Request completed: Request(0:C:0/1:0)
    	Brightness = 0.500000
    	ExposureTime = 29999
    	FocusFoM = 385
    	AnalogueGain = 2.151261
    	ColourCorrectionMatrix = [ 1.707466, -0.635721, -0.071751, -0.407837, 2.002241, -0.594406, -0.086645, -0.653424, 1.740068 ]
    	FrameDuration = 33326
    	Lux = 377.171906
    	AeLocked = false
    	ColourGains = [ 1.771746, 1.573529 ]
    	DigitalGain = 1.000000
    	ColourTemperature = 4809
    	SensorBlackLevels = [ 4096, 4096, 4096, 4096 ]
    	ScalerCrop = (0, 2)/3280x2460
    	SensorTimestamp = 14648048007000
     seq: 000007 timestamp: 14648048007000 bytesused: 480000/240000
    

Build libcamera-apps

Finally, let’s see how to manage libcamera-apps, so we quickly download the source, install the required packages and build with the previous workable cross-file.

sbuild-apt rpi-$RELEASE-$ARCH apt-get install libpng-dev libcamera-dev libjpeg-dev libtiff5-dev libboost-all-dev libdrm-dev libexif-dev
git clone <https://github.com/raspberrypi/libcamera-apps.git>
cd libcamera-apps
ln -s ../rpi_cross_file.txt
../meson/meson.py setup --wipe build -Denable_libav=true -Denable_drm=true -Denable_egl=true -Denable_qt=true -Denable_opencv=false -Denable_tflite=false --cross-file rpi_cross_file.txt
../meson/meson.py compile -C build

The first try results in the below failed message:

[2/39] Compiling C++ object libcamera_app.so.1.2.1.p/core_post_processor.cpp.o
FAILED: libcamera_app.so.1.2.1.p/core_post_processor.cpp.o
/opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-g++ -Ilibcamera_app.so.1.2.1.p -I. -I.. -Icore -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libcamera -I/usr/include -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/aarch64-linux-gnu -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libpng16 -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libdrm -I/root/sys/chroots/rpi-bullseye-arm64/usr/include/ -I/root/sys/chroots/rpi-bullseye-arm64/usr/include/aarch64-linux-gnu/ -fdiagnostics-color=always -Wall -Winvalid-pch -Wextra -Wpedantic -Werror -std=c++17 -O3 -pedantic -Wno-unused-parameter -faligned-new -D_FILE_OFFSET_BITS=64 -Wno-psabi -ftree-vectorize -DLIBDRM_PRESENT=1 -Wno-variadic-macros -Wno-pedantic -fPIC -pthread -DBOOST_ALL_NO_LIB -MD -MQ libcamera_app.so.1.2.1.p/core_post_processor.cpp.o -MF libcamera_app.so.1.2.1.p/core_post_processor.cpp.o.d -o libcamera_app.so.1.2.1.p/core_post_processor.cpp.o -c ../core/post_processor.cpp
In file included from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/aarch64-rpi4-linux-gnu/bits/gthr-default.h:48,
                 from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/aarch64-rpi4-linux-gnu/bits/gthr.h:151,
                 from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/ext/atomicity.h:35,
                 from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/bits/ios_base.h:39,
                 from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/ios:42,
                 from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/ostream:38,
                 from /opt/x-tools/aarch64-rpi4-linux-gnu/aarch64-rpi4-linux-gnu/include/c++/10.5.0/iostream:39,
                 from ../core/post_processor.cpp:8:
/usr/include/pthread.h:31:10: fatal error: bits/types/struct___jmp_buf_tag.h: No such file or directory
   31 | #include <bits/types/struct___jmp_buf_tag.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

I found -I/usr/include in the build command, so I suspected that g++ includes the file from the Ubuntu container instead of from the sysroot. Therefore, I looked into the setup message and realized that meson used the boost from /usr instead of sysroot + /usr, which caused the compilation failure.

The Meson build system
Version: 1.2.99
Source dir: /root/main/libcamera-apps
Build dir: /root/main/libcamera-apps/build
Build type: cross build
Project name: libcamera-apps
Project version: 1.2.1
C compiler for the host machine: /opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-gcc (gcc 10.5.0 "aarch64-rpi4-linux-gnu-gcc (crosstool-NG 1.26.0_rc1) 10.5.0")
C linker for the host machine: /opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-gcc ld.bfd 1.26.0
C++ compiler for the host machine: /opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-g++ (gcc 10.5.0 "aarch64-rpi4-linux-gnu-g++ (crosstool-NG 1.26.0_rc1) 10.5.0")
C++ linker for the host machine: /opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-g++ ld.bfd 1.26.0
C compiler for the build machine: cc (gcc 11.4.0 "cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0")
C linker for the build machine: cc ld.bfd 2.38
C++ compiler for the build machine: c++ (gcc 11.4.0 "c++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0")
C++ linker for the build machine: c++ ld.bfd 2.38
Build machine cpu family: aarch64
Build machine cpu: aarch64
Host machine cpu family: aarch64
Host machine cpu: aarch64
Target machine cpu family: aarch64
Target machine cpu: aarch64
Found pkg-config: YES (/usr/bin/pkg-config) 0.29.2
Run-time dependency libcamera found: YES 0.0.5
Run-time dependency Boost (found: program_options) found: YES 1.74.0 (/usr) <----- this line
Run-time dependency threads found: YES
Found CMake: NO
Run-time dependency libavcodec found: NO (tried pkgconfig and cmake)
Run-time dependency libexif found: YES 0.6.22
Run-time dependency libjpeg found: YES 2.0.6
Run-time dependency libtiff-4 found: YES 4.2.0
Run-time dependency libpng found: YES 1.6.37
Run-time dependency libdrm found: YES 2.4.104
Run-time dependency x11 found: NO (tried pkgconfig and cmake)
Run-time dependency epoxy found: NO (tried pkgconfig and cmake)
qmake5 found: NO need ['>= 5', '< 6']
Run-time dependency qt5 (modules: Core, Widgets) found: NO (tried pkgconfig and config-tool)
Run-time dependency opencv4 found: NO (tried pkgconfig and cmake)
Run-time dependency tensorflow-lite found: NO (tried pkgconfig and cmake)
Build targets in project: 7

libcamera-apps 1.2.1

  libcamera
    location             : /usr/lib/aarch64-linux-gnu
    version              : 0.0.5

  Build configuration
    libav encoder        : NO
    drm preview          : YES
    egl preview          : NO
    qt preview           : NO
    OpenCV postprocessing: NO
    TFLite postprocessing: NO

  User defined options
    Cross files          : rpi_cross_file.txt
    prefix               : /root/main/libcamera-apps/installed_bin
    enable_drm           : true
    enable_egl           : true
    enable_libav         : true
    enable_opencv        : false
    enable_qt            : true
    enable_tflite        : false

Found ninja-1.10.1 at /usr/bin/ninja

To resolve this issue, I added a proper boost.pc in the sysroot to specify the prefix of the boost libraries to /root/sys/chroots/rpi-bullseye-arm64/usr

cd /root/sys/chroots/rpi-bullseye-arm64/usr/lib/aarch64-linux-gnu/pkgconfig
cat > boost.pc <<EOF
# Package Information for pkg-config

prefix=/root/sys/chroots/rpi-bullseye-arm64/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/boost
includedir_new=${prefix}/include

Name: Boost
Description: Boost is awesome
Version: 1.74.0
Libs: -L${exec_prefix}/lib  -lboost_prg_exec_monitor-mt
-lboost_math_c99f-mt -lboost_unit_test_framework-mt
-lboost_container-mt -lboost_log_setup -lboost_math_tr1l
-lboost_graph-mt -lboost_wserialization-mt -lboost_log-mt
-lboost_math_c99f -lboost_type_erasure -lboost_signals-mt
-lboost_test_exec_monitor -lboost_filesystem -lboost_thread-mt
-lboost_math_tr1f-mt -lboost_date_time -lboost_timer
-lboost_math_tr1f -lboost_test_exec_monitor-mt -lboost_container
-lboost_math_tr1 -lboost_type_erasure-mt
-lboost_program_options-mt -lboost_graph -lboost_log_setup-mt
-lboost_random -lboost_system -lboost_system-mt -lboost_locale-mt
-lboost_wserialization -lboost_regex -lboost_exception
-lboost_timer-mt -lboost_signals -lboost_filesystem-mt
-lboost_math_c99-mt -lboost_math_tr1-mt -lboost_serialization-mt
-lboost_serialization -lboost_prg_exec_monitor -lboost_exception-mt
-lboost_coroutine -lboost_math_c99 -lboost_iostreams-mt
-lboost_random-mt -lboost_program_options -lboost_atomic-mt
-lboost_date_time-mt -lboost_math_c99l -lboost_math_tr1l-mt
-lboost_context-mt -lboost_regex-mt -lboost_coroutine-mt
-lboost_log -lboost_chrono-mt -lboost_wave-mt
-lboost_iostreams -lboost_chrono -lboost_unit_test_framework
-lboost_math_c99l-mt
Cflags: -I\\${includedir_old} -I\\${includedir_new}
EOF

Add --wipe to set up the build again and compile, and the "include errors" were gone.

../meson/meson.py setup --wipe build -Denable_libav=true -Denable_drm=true -Denable_egl=true -Denable_qt=true -Denable_opencv=false -Denable_tflite=false --cross-file rpi_cross_file.txt
../meson/meson.py compile -C build
FAILED: libcamera_app.so.1.2.1.p/encoder_encoder.cpp.o
/opt/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-g++ -Ilibcamera_app.so.1.2.1.p -I. -I.. -Icore -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libcamera -I/root/sys/chroots/rpi-bullseye-arm64/usr/include -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/aarch64-linux-gnu -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libpng16 -I/root/sys/chroots/rpi-bullseye-arm64//usr/include/libdrm -I/root/sys/chroots/rpi-bullseye-arm64/usr/include/ -I/root/sys/chroots/rpi-bullseye-arm64/usr/include/aarch64-linux-gnu/ -fdiagnostics-color=always -Wall -Winvalid-pch -Wextra -Wpedantic -Werror -std=c++17 -O3 -pedantic -Wno-unused-parameter -faligned-new -D_FILE_OFFSET_BITS=64 -Wno-psabi -ftree-vectorize -DLIBDRM_PRESENT=1 -fPIC -pthread -DBOOST_ALL_NO_LIB -MD -MQ libcamera_app.so.1.2.1.p/encoder_encoder.cpp.o -MF libcamera_app.so.1.2.1.p/encoder_encoder.cpp.o.d -o libcamera_app.so.1.2.1.p/encoder_encoder.cpp.o -c ../encoder/encoder.cpp
In file included from /root/sys/chroots/rpi-bullseye-arm64/usr/include/linux/posix_types.h:5,
                 from /root/sys/chroots/rpi-bullseye-arm64/usr/include/linux/types.h:9,
                 from /root/sys/chroots/rpi-bullseye-arm64/usr/include/linux/stat.h:5,
                 from /root/sys/chroots/rpi-bullseye-arm64//usr/include/aarch64-linux-gnu/bits/statx.h:31,
                 from /root/sys/chroots/rpi-bullseye-arm64//usr/include/aarch64-linux-gnu/sys/stat.h:446,
                 from ../encoder/encoder.cpp:11:
/root/sys/chroots/rpi-bullseye-arm64/usr/include/linux/stddef.h:26:49: error: ISO C++ does not permit named variadic macros **[-Werror=variadic-macros]**
   26 | #define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \\
      |                                                 ^~~
In file included from /root/sys/chroots/rpi-bullseye-arm64//usr/include/aarch64-linux-gnu/bits/fcntl.h:61,
                 from /root/sys/chroots/rpi-bullseye-arm64/usr/include/fcntl.h:35,
                 from ../encoder/encoder.cpp:9:
/root/sys/chroots/rpi-bullseye-arm64//usr/include/aarch64-linux-gnu/bits/fcntl-linux.h:362:26: error: ISO C++ forbids zero-size array 'f_handle' **[-Werror=pedantic]**
  362 |   unsigned char f_handle[0];
      |

But the following warning: I cannot find a proper way to navigate them, [-Werror=variadic-macros] and [-Werror=pedantic]. All can do is suppress the warning by adding -Wno-variadic-macros and -Wno-pedantic to cpp_args in rpi_cross_file.txt as a temporary workaround, and after that, all compilation finished successfully.

(rpi_cross_file.txt)
[constants]
toolchain_dir = '/opt/x-tools/aarch64-rpi4-linux-gnu/bin/'
target_setting = 'aarch64-rpi4-linux-gnu'
c_sys_root = '/root/sys/chroots/rpi-bullseye-arm64/'
[binaries]
c = toolchain_dir / target_setting + '-gcc'
cpp = toolchain_dir / target_setting + '-g++'
strip = toolchain_dir / target_setting + 'strip'
pkg-config = '/usr/bin/pkg-config'
[properties]
sys_root = c_sys_root
pkg_config_libdir = sys_root + 'usr/lib/aarch64-linux-gnu/pkgconfig'
[built-in options]
cpp_args = ['-I' + c_sys_root + 'usr/include/','-I' + c_sys_root + 'usr/include/aarch64-linux-gnu/', '-Wno-variadic-macros', '-Wno-pedantic']
cpp_link_args = ['-Wl,-rpath,' + c_sys_root + 'lib/aarch64-linux-gnu/', '-Wl,-rpath-link,' + c_sys_root + 'lib/aarch64-linux-gnu/']
[host_machine]
system = 'Linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
(build command)
../meson/meson.py setup --wipe build -Denable_libav=true -Denable_drm=true -Denable_egl=true -Denable_qt=true -Denable_opencv=false -Denable_tflite=false --cross-file rpi_cross_file.txt
../meson/meson.py compile -C build
../meson/meson.py configure build --prefix=$(pwd)/installed_bin
../meson/meson.py install -C build
  • Move the installed_bin to RPI4 and test, and it worked. I can see the captured image from libcamera-still I built
(In RPI4)
cd installed_bin/bin
LD_LIBRARY_PATH=../lib/ ./libcamera-still -n -o test.jpeg
pi@raspberrypi:~/installed_bin/bin $ LD_LIBRARY_PATH=../lib/ ./libcamera-still -n -o test.jpeg
[7:34:57.848380731] [3001]  INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
[7:34:57.901412896] [3002]  WARN RPI vc4.cpp:383 Mismatch between Unicam and CamHelper for embedded data usage!
[7:34:57.902202812] [3002]  INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media4 and ISP device /dev/media0
[7:34:57.902256701] [3002]  INFO RPI pipeline_base.cpp:1101 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[7:34:57.903167208] [3001]  INFO Camera camera.cpp:1033 configuring streams: (0) 1640x1232-YUV420
[7:34:57.903809126] [3002]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1640x1232-SBGGR10_1X10 - Selected unicam format: 1640x1232-pBAA
[7:35:03.027655665] [3001]  INFO Camera camera.cpp:1033 configuring streams: (0) 3280x2464-YUV420 (1) 3280x2464-SBGGR10_CSI2P
[7:35:03.034392006] [3002]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 3280x2464-SBGGR10_1X10 - Selected unicam format: 3280x2464-pBAA
Still capture image received


(The camera)

 (The captured picture from the camera)

  • But it failed when I wanted to capture video, so the next step is to debug using gdb from the toolchain.
pi@raspberrypi:~/installed_bin/bin $ LD_LIBRARY_PATH=../lib/ ./libcamera-vid -n -o test.h264
ERROR: *** Invalid time string provided ***

Conclusion

The goal is almost accomplished; I can build my own apps now. However, libcamera-vid does not work properly, so the next step is to develop and debug in this compilation environment.

Comments

Popular posts from this blog

RPI camera → website → Chromecast → TV: (2) Streaming the video to TV

 RPI camera → website → Chromecast → TV: (2) Streaming the video to TV Why am I doing this? As an unemployed engineer, I need to find interesting things to fill my leisure time. I found there is a thing I can do to make my life more convenient to see the toys under my couch without in the crowing position of bending my knee and waist to find the toys which are "eaten by the couch," my kids said. Maybe I can use a camera on RPI to see the area under the couch and project the streaming video onto the TV by Chromecast. That is my initial thought. Devices An RPI4 A V2 camera My computer that I can run a server on. A Chromecast and TV Goal Streaming the video to TV From the previous post , I can stream camera data from RPI to my computer; this time, I need to project the camera data to my TV. There are many ways to send the video to TV. My initial thoughts are that if I can write a website to show videos, I can project the webpage using the browser's built-in button, and all t

RPI camera → website → Chromecast → TV: (1) Capture video by RPI

 RPI camera → website → Chromecast → TV: (1) Capture video by RPI Why am I doing this? As an unemployed engineer, I need to find interesting things to fill my leisure time. I found there is a thing I can do to make my life more convenient to see the toys under my couch without in the crowing position of bending my knee and waist to find the toys which are “eaten by the couch,” my kids said. Maybe I can use a camera on RPI to see the area under the couch and project the streaming video onto the TV by Chromecast. That is my initial thought. Devices An RPI4 A V2 camera My computer that I can run a server on. A Chromecast and TV Goal Capture video by RPI libcamera-vid libcamera-vid is a built-in app for the RPI system. I found that the network streaming functionality can be enabled with libcamera-vid terminal command line, written in the official document . Thus, I can send the streamed video using the app by UDP, TCP, or RTSP. Benchmark setting The RPI camera captures the computer