简体   繁体   中英

How do I cross compile OpenCV for the Raspberry Pi with additional modules (highgui…)

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 (eg "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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM