---
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.