Reputation: 469
My goal is to cross-compile OpenCV for Raspberry Pi with CMake on an Ubuntu 16.04 Host. The Problem lies within the CMake toolchain file which is unable to handle the compilation process correctly. As soon as pkg-config comes into play, a lot of "fatal error: No such file or directory" errors arise (e.g. "fatal error: gtk/gtk.h: No such file or directory).
I figured out that further "-isystem" flags with the directories containing the missing files seem to help in some way, but I doubt that this is the right way to address these errors.
The toolchain file works, as long as the "PKG_CONFIG"-stuff is commented out. This causes pkg-config not to find "libgtk2.0", which is needed for OpenCV's highgui module and builds without highgui-support.
Some ideas for the toolchain are from here:
build-toolchain.sh
#!/bin/bash
# apt -y install lib32z1 libstdc++6:i386 git qemu-user proot cmake pkg-config
MOUNT_DIR=/mnt/rasp-pi-rootfs
TEMP_DIR=/tmp/build
RASPBIAN_IMG_ZIP=raspbian-jessie.zip
TOOLCHAIN=gcc-linaro-arm-linux-gnueabihf-raspbian-x64
CMAKE_TOOLCHAIN_FILE=rpi-toolchain.cmake
############################################################################
RASPBIAN_IMG=${TEMP_DIR}/$(unzip -Z1 $RASPBIAN_IMG_ZIP)
rm -rf $TEMP_DIR
mkdir $TEMP_DIR
cd $TEMP_DIR
#unzip raspbian-img
unzip $RASPBIAN_IMG_ZIP
#resize raspbian-img
LOOP_DEVICE=$(losetup -f)
RASPBIAN_PARTITION_BOOT=${LOOP_DEVICE}p1
RASPBIAN_PARTITION_SYSTEM=${LOOP_DEVICE}p2
truncate -s +500M $RASPBIAN_IMG
losetup $LOOP_DEVICE $RASPBIAN_IMG
parted $LOOP_DEVICE resizepart 2 100%
#wait until auto-mounted
umount $RASPBIAN_PARTITION_BOOT
umount $RASPBIAN_PARTITION_SYSTEM
e2fsck -f $RASPBIAN_PARTITION_SYSTEM
resize2fs $RASPBIAN_PARTITION_SYSTEM
#mount raspbian-img
mkdir -p $MOUNT_DIR
mount $RASPBIAN_PARTITION_SYSTEM $MOUNT_DIR
#fix absolute links
proot -q qemu-arm -S $MOUNT_DIR<<EOF
apt update
apt -y install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev \
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
libxvidcore-dev libx264-dev \
libgtk2.0-dev libatlas-base-dev gfortran
apt -y install symlinks
symlinks -cr /usr/lib
EOF
wget -O opencv.zip https://codeload.github.com/Itseez/opencv/zip/2.4.13
unzip opencv.zip
cd opencv-*
mkdir build
cd build
cmake -D CMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE -D PIROOT=$MOUNT_DIR -D TOOLROOT=$TOOLCHAIN -D CMAKE_BUILD_TYPE=Release -D WITH_V4L=ON -D WITH_OPENGL=ON ..
make -j $(nproc)
make install
sync; umount $MOUNT_DIR
losetup -d $LOOP_DEVICE
rpi-toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER ${TOOLROOT}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${TOOLROOT}/bin/arm-linux-gnueabihf-g++)
set(CMAKE_SYSROOT ${PIROOT})
set(CMAKE_FIND_ROOT_PATH ${PIROOT})
unset(ENV{PKG_CONFIG_DIR})
set(ENV{PKG_CONFIG_LIBDIR} "$ENV{PKG_CONFIG_LIBDIR}:${PIROOT}/usr/lib/arm-linux-gnueabihf/pkgconfig:${PIROOT}/usr/share/pkgconfig:${PIROOT}/usr/lib/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${PIROOT}")
set(FLAGS "-isystem ${PIROOT}/usr/include/arm-linux-gnueabihf")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}" CACHE STRING "" 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)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_INSTALL_PREFIX ${PIROOT}/usr/local)
Upvotes: 4
Views: 2909
Reputation: 469
Got it. The Problem was the setting of PKG_CONFIG-vars within the rpi-toolchain.cmake file, this does not work .They have to be added to the environment with export:
...
export PKG_CONFIG_SYSROOT_DIR=${MOUNT_DIR}
export PKG_CONFIG_LIBDIR=${MOUNT_DIR}/usr/lib/arm-linux-gnueabihf/pkgconfig:${MOUNT_DIR}/usr/share/pkgconfig:${MOUNT_DIR}/usr/lib/pkgconfig
export PKG_CONFIG_DIR=
cmake -D CMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE -D PIROOT=$MOUNT_DIR -D TOOLROOT=$TOOLCHAIN -D CMAKE_BUILD_TYPE=Release -D WITH_V4L=ON -D WITH_OPENGL=ON ..
make -j $(nproc)
edit: I don't remember what the actual problem was here, but setting pkg-config variables with ENV{}
works and was not the culprit.
Upvotes: 4