4

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)
zer0
  • 451
  • 4
  • 10
  • while this is a programming tools Q (I think), you might get more sympathy and expertise by moving this Q to http://raspberrypi.stackexchange.com. did you find the path to `..../gtk/gtk.h` on your machine? (and of course all the other missing include files). If this was a traditional Makefile, then I would add that dir to the `-I` and the related `-L` dir (binaries) to definitions at the top, but I don't see anything like that in Cmake. Good luck! – shellter Nov 19 '16 at 04:28
  • The files are definitely there (see `apt -y install libgtk2.0-dev`), when I try to compile it directly on the Pi it's working. If the path is added via "-isystem" to the compiler flag, gcc is able to find it. However, this does not look like a clean solution to me, since other errors in the same manner arise and I thought it was pkg-config's job to configure this properly ([include all /usr/include](https://stackoverflow.com/questions/510098/g-include-all-usr-include-recursively))? – zer0 Nov 19 '16 at 06:49

1 Answers1

4

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.

zer0
  • 451
  • 4
  • 10