--- tags: tutorial, cross_compile --- # Cross Compile OpenCV using Pi-cross ## Prepare pi-cross Pull the arch you need from pi-cross. In this example, `aarch64`, `bullseye` and `g++ 10.2.0` are uesd for rpi 4 bullseye 64 bit os. ```bash= docker pull wesleych3n/pi-cross:arm64-bullseye-10.2.0 ``` Create helper script and grant it execution privilege ```bash= docker run --rm wesleych3n/pi-cross:arm64-bullseye-10.2.0 > ./arm64-10.2.0 chmod +x ./arm64-10.2.0 ``` Place script to the `$PATH`. For me, `~/.local/bin` ```bash= mv ./arm64-10.2.0 ~/.local/bin ``` ## Compiling OpencCV Goto your working directory and create pi-cross shell. ```bash= arm64-10.2.0 bash ``` Note: The working directory are *MOUNTED* into `/work` inside pi-cross container. Start Compiling, Getting source code, ```bash= # In pi-cross # if you need to apt install something change arch first like below # sudo dpkg --add-architecture arm64 # sudo dpkg --print-foreign-architectures # get opencv source code wget -O opencv.zip https://github.com/opencv/opencv/archive/4.6.0.zip wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.6.0.zip unzip opencv.zip unzip opencv_contrib.zip mv opencv-4.5.0 opencv mv opencv_contrib-4.5.0 opencv_contrib ``` Start Cmake with the option you need. Basically I need static lib with minimum requirements of image format. Also, I specify the installation path to `/opt` (default will be `/usr/local/`) ```bash= mkdir -p opencv/build/ && cd opencv/build cmake -D CMAKE_INSTALL_PREFIX=/opt/opencv \ -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \ -D CMAKE_BUILD_TYPE=RELEASE \ -D BUILD_SHARED_LIBS=OFF \ -D BUILD_DOCS=OFF \ -D BUILD_EXAMPLES=OFF \ -D INSTALL_C_EXAMPLES=OFF \ -D BUILD_opencv_apps=OFF \ -D WITH_CAROTENE=OFF \ -D BUILD_opencv_python2=OFF \ -D BUILD_opencv_python3=OFF \ -D BUILD_PERF_TESTS=OFF \ -D BUILD_TESTS=OFF \ -D FORCE_VTK=OFF \ -D WITH_FFMPEG=OFF \ -D WITH_GDAL=OFF \ -D WITH_IPP=OFF \ -D WITH_OPENEXR=OFF \ -D WITH_OPENGL=OFF \ -D WITH_QT=OFF \ -D WITH_TBB=OFF \ -D WITH_XINE=OFF \ -D BUILD_JPEG=ON \ -D BUILD_ZLIB=ON \ -D BUILD_PNG=OFF \ -D BUILD_TIFF=OFF \ -D BUILD_BUILD_JASPER=OFF \ -D WITH_ITT=OFF \ -D WITH_LAPACK=OFF \ -D WITH_OPENCL=OFF \ -D WITH_TIFF=OFF \ -D WITH_PNG=OFF \ -D WITH_OPENCLAMDFFT=OFF \ -D WITH_OPENCLAMDBLAS=OFF \ -D WITH_VA_INTEL=OFF \ -D WITH_WEBP=OFF \ -D WITH_JASPER=OFF \ -D OPENCV_GENERATE_PKGCONFIG=ON .. # on 32 bit, better to open these two # -D ENABLE_NEON=ON \ # -D ENABLE_VFPV3=ON \ ``` Make sure cmake indicate the right cross compiler at the final output as below: ```bash! ... -- C++ Compiler: /usr/local/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ (ver 10.2.0) ... ``` Start compiling. Enjoy the speed from cross-compiling :heart:. ```bash= make -j 8 mkdir install_aarch64 make DESTDIR=./install_aarch64 install ``` Because we don't want to install opencv to the container `/opt`, it will disappear as you exit pi-cross. So just create a folder inside `/work` and install in it. ```bash= make -j 8 mkdir install_aarch64 make DESTDIR=./install_aarch64 install ``` The lib and header file are all in `./install_aarch64`. Exit pi-cross. Finished :confetti_ball: . ## How to use the lib to compile your program by Pi-cross?? The fastest way to show you is the example. Create following files in working directory. `main.cc` ```cpp= #include <iostream> #include "opencv2/opencv.hpp" int main(int argc, char *argv[]) { cv::Mat img = cv::imread("../test.jpg"); std::cout << img.size << '\n'; return 0; } ``` `CMakeLists.txt` ```cmake= cmake_minimum_required(VERSION 3.10) project(opencv_example) find_package(PkgConfig REQUIRED) pkg_check_modules(OPENCV REQUIRED opencv4) include_directories(${OPENCV_INCLUDE_DIRS}) add_executable(main main.cc) target_link_libraries(main ${OPENCV_STATIC_LDFLAGS}) ``` Create pi-cross container. There are two things need to mount into container. First, `opencv4.pc` is for `pkg-config` to find the right place of opencv lib. Second of course is to mount opencv lib to `/opt` we set earlier. The way we mount is to use `-a` to pass docker mount arguments. ```bash arm64-10.2.0 -a \ "-v $PWD/opencv/aarch64/opt/opencv/lib/pkgconfig/opencv4.pc:/usr/lib/pkgconfig/opencv4.pc:ro \ -v $PWD/opencv/aarch64/opt:/opt/" bash ``` create build directory and build the executable ```bash= mkdir build && cd build cmake .. make ``` then the `main` executable can run on your aarch64 system.