第109話 OpenCV4 クロスビルドの巻(x86-64 to ARMv7/ARMv8/RISCV)

この記事は[OpenCV Advent Calendar 2023](https://qiita.com/advent-calendar/2023/opencv)の4日目の記事です。
他の記事は目次にまとめられています。

■ TL;DR: Multiarchでクロスビルドが簡単に！
=========================================
- Ubuntu/Debianには、Multiarchという仕組みがあり、異アーキテクチャを混在できる
- OpenCVのクロスビルドに使うと、他Archのバイナリが簡単に作れる

◯freetype wrapper moduleがクロスビルド？できらぁ！
------------------------------------------------------
年に数回、中国語で「クロスビルドしようと思ったら、freetypeでエラーになる」って怒られが発生する。

https://github.com/opencv/opencv_contrib/issues/3553

クロスビルド方法についてドキュメント書いた方がいい、ということで手順を紹介する、日本語でね。

◯FFmpegつかってクロスビルド？できらぁ！
-------------------------------------
FFmpegを有効化したい、でも、クロスコンパイル環境だとライブラリがいないから、、、とご心配の貴方に朗報です！この手段であれば、行けます！！

◯Python binding ?できらぁ！
---------------------------------------------------
Python wrapperを有効化するためのオプションを指定することもできます。

◯今回のポイント
---------------
- Ubuntu/Debianには、Multiarchという仕組みがあり、異アーキテクチャを混在できる
  - 他アーキのディスクイメージとか面倒なものは要らないでございます 
- OpenCVのクロスビルドに使うと、他Archのバイナリが簡単に作れる
- JetsonもRaspiOSも、みんなdebian系列で友達友達！！ここらへんも適切なhost側OSを選択すれば、クロスコンパイルできるはず！！

さあ、Let's cross compile !!

◯そもそもMultiarchって何？
--------------------------
https://help.ubuntu.com/community/MultiArch

> If Ubuntu is working, you should not have to concern yourself with the details of how it supports different computer architectures; just install the programs you like.
> (翻訳) Ubuntu が動作している場合は、Ubuntu がさまざまなコンピューター アーキテクチャをサポートする方法の詳細を気にする必要はありません。好きなプログラムをインストールするだけです。

ということで、後述の例でも出ますが、host以外にtargetのライブラリも同時にインストールできるようになっております！！

■ 準備
======

:::note alert
なお、これをやるとHostのLinux環境が汚れるので、VMやコンテナ(Docker)を使う事をお勧めします
:::



◯ディレクトリ構成のイメージ
---------------------------

今回は以下のような構成を想定して進めていきます。

なお、基本的には、`/home/<ユーザ名>/work` 直下で作業をするイメージです。

```plaintext:directories
/home
  + kmtr                    - please replace your account name.
    + work
      + opencv              - source, cloned from github
      + opencv_contrib      - source, cloned from github
      + build4-main         - artifact(for Host), created by cmake
      + build4-full         - artifact(for Host), created by cmake
      + build4-full_arm64   - artifact(for aarch64 target), created by cmake
      + build4-full_armhf   - artifact(for armhf target), created by cmake
      + build4-full_riscv64 - artifact(for riscv64 target), created by cmake
```

```bash
cd
mkdir work
cd wotk
```

◯必要なライブラリのインストール
------------------------------

それでは、OpenCVの開発に必要なライブラリをインストールしていく。
`crossbuild-essential-armhf`と`crossbuild-essential-arm64` をインストールすると、クロス開発に必要なアレやコレやソレが全部入る。素敵ですね！！

```ライブラリのインストール
sudo apt install -y \
    git \
    cmake \
    cmake-curses-gui \
    ccache \
    ninja-build \
    libfreetype-dev \
    libharfbuzz-dev \
    build-essential \
    crossbuild-essential-armhf \
    crossbuild-essential-arm64
```

◯ OpenCVのソースコードをclone
-----------------------------

ここらへんはいつもの手順ですね。

```bash
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
```

なお、特定バージョンをbuildしたい場合は、`git switch`を使います。

```bash
cd opencv
git switch 4.8.0
git reset --hard
cd ..
cd opencv_contrib
git switch 4.8.0
git reset --hard
cd ..
```

■ Host版OpenCVビルド
====================

<details>
<summary>Host版OpenCVビルドなので興味があったら開いてください</summary>

◯contrib抜き
-------------

cmakeを使って、build用の環境を整備する。必要に応じて、`ccmake`コマンドなどで微調整しても良い。

```bash
cmake -S opencv \
      -B build4-main \
      -GNinja
```

```plaintext
-- General configuration for OpenCV 4.8.0-dev =====================================
--   Version control:               4.8.0-XXX-XXXXXXXX
--
--   Platform:
--     Timestamp:                   2023-09-17T00:01:52Z
--     Host:                        Linux 6.2.0-32-generic x86_64
--     CMake:                       3.25.1
--     CMake generator:             Ninja
--     CMake build tool:            /usr/bin/ninja
--     Configuration:               Release
```

特に問題が無ければ、サクッとbuildもinstallもできるはず。

```bash
     cmake --build   build4-main
sudo cmake --install build4-main
sudo ldconfig
```


◯contrib入り
-------------

contrib入りでbuildをするべく、`OPENCV_EXTRA_MODULES_PATH`を指定する。

```bash
cmake -S opencv \
      -B build4-full \
      -DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules \
      -GNinja
```

cmakeの結果にも`Extra modules`が追加される。

```plaintext
-- General configuration for OpenCV 4.8.0-dev =====================================
--   Version control:               4.8.0-237-XXXXXXXX
--
--   Extra modules:
--     Location (extra):            /home/kmtr/work/opencv_contrib/modules
--     Version control (extra):     4.8.0-17-XXXXXXXX
--
--   Platform:
--     Timestamp:                   2023-09-17T00:35:16Z
--     Host:                        Linux 6.2.0-32-generic x86_64
--     CMake:                       3.25.1
--     CMake generator:             Ninja
--     CMake build tool:            /usr/bin/ninja
--     Configuration:               Release
```

あとは普通にまたbuild/install.

```bash
     cmake --build   build4-full
sudo cmake --install build4-full
sudo ldconfig
```

</details>

■ Target版OpenCVビルド(arm64)
=============================

さて、ここからが本番。

◯/etc/apt/sources.listの修正
-----------------------------

`sudo apt edit-sources` を使い、インストールするarchを追加していく。なお、私はvi大好きなので、2を選んでいるけど、なんでしたら`/bin/ed`を選んでいただいてもよいのですよ（？）。

```bash
sudo apt edit-sources
 
Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.tiny
  3. /bin/ed
 
Choose 1-3 [1]: 2
```

例えば、ubuntu23.04の場合は以下の行を追加する。これによって、x86-64のhost環境でも、arm64とarmhfのtarget環境のパッケージを入れられる。

```plaintext
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar main restricted
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-updates main restricted
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar universe
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-updates universe
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar multiverse
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-updates multiverse
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-backports main restricted universe multiverse
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-security main restricted
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-security universe
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports lunar-security multiverse
```

例えば、ubuntu23.10の場合は以下の行を追加する。
なお、risc64にも対応させたいならば、`,riscv64`も追加する。

```plaintext
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic main restricted
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-updates main restricted
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic universe
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-updates universe
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic multiverse
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-updates multiverse
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-backports main restricted universe multiverse
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-security main restricted
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-security universe
deb [arch=arm64,armhf] http://ports.ubuntu.com/ubuntu-ports mantic-security multiverse
```

最後に、データベースを更新する。

```bash
sudo apt update
```


◯dpkg側の設定更新
------------------

aptの内側にいるdpkgにも、アーキ追加のお知らせをする。そうしないとapt installできない。

```bash
sudo dpkg  --add-architecture arm64
sudo dpkg  --add-architecture armhf
sudo dpkg  --add-architecture riscv64 %riscv64
```

以下コマンドで現状のarchを確認できる。

```bash
$ sudo dpkg  --print-architecture
amd64
$ sudo dpkg  --print-foreign-architectures
arm64
armhf
```

◯pkg-configの動作確認
---------------------

Host向け、Target向けのライブラリに対して、pkg-configが正常動作できることを確認する。

ディレクトリ構成はこんな感じになっている。

```plaintext
/usr
  + lib
    + aarch64-linux-gnu   - shared libraries for arm64
      + pkgconfig         - pkg-config files(for shared libraries)
    + arm-linux-gnueabihf - shared libraries for armhf
      + pkgconfig         - pkg-config files(for shared libraries)
  + share
    + pkgconfig         - pkg-config files(for header files)
```

#### Host向け

```
pkg-config --list-all
```

#### Target(armhf)向け

```
PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig \
PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf \
PKG_CONFIG_SYSROOT_DIR=/ \
    pkg-config --list-all
```

#### Target(arm64)向け

```
PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu \
PKG_CONFIG_SYSROOT_DIR=/ \
    pkg-config --list-all
```

◯arm64向けbuild
----------------

#### freetype/harfbuzzのインストール

arm64向けのfreetypeとharfbuzzをインストールする。arm64と後ろにつけるのがポイント！

ちゃんとできていると、pkg-configで確認できる。

```bash
sudo apt install libfreetype-dev:arm64 libharfbuzz-dev:arm64

PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu \
    PKG_CONFIG_SYSROOT_DIR=/ \
       pkg-config freetype2 harfbuzz --cflags --libs
 
-I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/aarch64-linux-gnu/glib-2.0/include -L/usr/lib/aarch64-linux-gnu -lfreetype -lharfbuzz
```

#### cmake
cmakeを実行していく。`CMAKE_TOOLCHAIN_FILE`は、相対パスではなく絶対パスで指定が必要。

```bash
PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu \
    PKG_CONFIG_SYSROOT_DIR=/ \
        cmake -S opencv \
              -B build4-full_arm64 \
              -DCMAKE_TOOLCHAIN_FILE=/home/kmtr/work/opencv/platforms/linux/aarch64-gnu.toolchain.cmake \
              -DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules \
              -GNinja
```

cmakeが成功すと、`Host`がx86_64、`Target`がaarch64になる。

```plaintext
-- General configuration for OpenCV 4.8.0-dev =====================================
--   Version control:               4.8.0-237-XXXXXXXX
--
--   Extra modules:
--     Location (extra):            /home/kmtr/work/opencv_contrib/modules
--     Version control (extra):     4.8.0-17-XXXXXXXX
--
--   Platform:
--     Timestamp:                   2023-09-17T01:31:30Z
--     Host:                        Linux 6.2.0-32-generic x86_64
--     Target:                      Linux 1 aarch64
--     CMake:                       3.25.1
--     CMake generator:             Ninja
--     CMake build tool:            /usr/bin/ninja
--     Configuration:               Release
```

#### build & install

あとは今まで通り、普通にbuildする。

```bash
     cmake --build   build4-full_arm64
sudo cmake --install build4-full_arm64
```

build結果は、installパスに入っているので、適当な手段でtargetにコピーする。

targetでは、`/usr/local/include/opencv4`などに必要なファイルをコピーするなどすればよい。

#### targetでlibrariesのインストール

さて、ここでtarget側での作業になる。これまでbuildしたopencvはhost側環境でインストールしたライブラリに依存している。ということは、targetにコピーしただけだと動かない。

```bash
ldd /usr/local/lib/libopencv_freetype.so
        linux-vdso.so.1 (0xABCDEFG01234567)
        libopencv_imgproc.so.408 => /usr/local/lib/libopencv_imgproc.so.408 (0xABCDEFG01234567)
        libfreetype.so.6 => /lib/aarch64-linux-gnu/libfreetype.so.6 (0xABCDEFG01234567)
        libharfbuzz.so.0 => not found
        libopencv_core.so.408 => /usr/local/lib/libopencv_core.so.408 (0xABCDEFG01234567)
```

そこで、target側でも必要なライブラリをインストールする。

```
sudo apt install libfreetype-dev libharfbuzz-dev
sudo ldconfig

ldd /usr/local/lib/libopencv_freetype.so
        linux-vdso.so.1 (0xABCDEFG01234567)
        libopencv_imgproc.so.408 => /usr/local/lib/libopencv_imgproc.so.408 (0xABCDEFG01234567)
        libfreetype.so.6 => /lib/aarch64-linux-gnu/libfreetype.so.6 (0xABCDEFG01234567)
        libharfbuzz.so.0 => /lib/aarch64-linux-gnu/libharfbuzz.so.0 (0xABCDEFG01234567)
        libopencv_core.so.408 => /usr/local/lib/libopencv_core.so.408 (0xABCDEFG01234567)
```

これで万事解決！ばんじゃーい！ばんじゃーい！


◯ FFmpegを有効化したいよ！
-------------------------
そんな時は、Hostにインストールするライブラリを足しましょう！！

```diff
  sudo apt install -y \
+   libavcodec-dev:arm64 \
+   libavformat-dev:arm64 \
+   libavutil-dev:arm64 \
+   libswscale-dev:arm64 \
    libfreetype-dev:arm64 \
    libharfbuzz-dev:arm64
```

そして、cmakeコマンドで、コンフィグレーション作り直せばオッケー！！

```
--
--   Video I/O:
--     DC1394:                      NO
--     FFMPEG:                      YES
--       avcodec:                   YES (60.3.100)
--       avformat:                  YES (60.3.100)
--       avutil:                    YES (58.2.100)
--       swscale:                   YES (7.1.100)
--       avresample:                NO
--     GStreamer:                   NO
--     v4l/v4l2:                    YES (linux/videodev2.h)
```

◯ Python bindingも有効化したいよ！
-------------------------
Python binding有効化するときは、ちょっと工夫が必要。

お手持ちのPython Versionが、3.9なのか3.10なのか3.11なのか、という情報が必要。
ちょっとトリッキーだけど、こんな感じで、cmake実行時にオプションを追加してあげる。

```
PYTHON3_REALPATH=`realpath /usr/bin/python3`
PYTHON3_BASENAME=`basename ${PYTHON3_REALPATH}`
PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu \
    PKG_CONFIG_SYSROOT_DIR=/ \
        cmake -S opencv \
              -B build4-full_arm64 \
              -DCMAKE_TOOLCHAIN_FILE=/home/kmtr/work/opencv/platforms/linux/aarch64-gnu.toolchain.cmake \
              -DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules \
              -DPYTHON3_NUMPY_INCLUDE_DIRS="/usr/local/lib/${PYTHON3_BASENAME}/dist-packages/numpy/core/include/" \
              -DPYTHON3_INCLUDE_PATH="/usr/include/${PYTHON3_BASENAME};/usr/include/" \
              -DPYTHON3_LIBRARIES=`find /usr/lib/aarch64-linux-gnu/ -name libpython*.so` \
              -DPYTHON3_EXECUTABLE="/usr/bin/${PYTHON3_BASENAME}" \
              -DPYTHON3_CVPY_SUFFIX=".so" \
              -GNinja
```

上手くできると、こんな感じにpythonの環境変数が認識される（念のため、フォルダを一度消した方がいいかも）

```
--
--   Python 3:
--     Interpreter:                 /usr/bin/python3.11 (ver 3.11.6)
--     Libraries:                   /usr/lib/aarch64-linux-gnu/libpython3.11.so
--     numpy:                       /usr/local/lib/python3.11/dist-packages/numpy/core/include/ (ver undefined - cannot be probed because of the cross-compilation)
--     install path:                lib/python3.11/dist-packages/cv2/python-3.11
--
--   Python (for build):            /usr/bin/python3.11
--
```

■ Target版OpenCVビルド(armhf)
=============================

大体手順としては、arm64に準じる。
- `linux-libc-dev:armhf` を手動インストールしないと、依存関係でエラーになる。
- `-DENABLE_NEON=ON`を付けると、NEONを使った最適化が有効になる。


```bash
sudo apt install linux-libc-dev:armhf
sudo apt install libfreetype-dev:armhf libharfbuzz-dev:armhf
 
PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/arm-linux-gnueabihf/ \
    PKG_CONFIG_SYSROOT_DIR=/ \
       pkg-config freetype2 harfbuzz --cflags --libs
(output) -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/arm-linux-gnueabihf/glib-2.0/include -L/usr/lib/arm-linux-gnueabihf -lfreetype -lharfbuzz
 
PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf \
    PKG_CONFIG_SYSROOT_DIR=/ \
        cmake -S opencv \
              -B build4-full_armhf \
              -DENABLE_NEON=ON \
              -DCMAKE_TOOLCHAIN_FILE=/home/kmtr/work/opencv/platforms/linux/arm-gnueabi.toolchain.cmake \
              -DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules \
              -GNinja
 
cmake      --build   build4-full_armhf
sudo cmake --install build4-full_armhf
```

■ Target版OpenCVビルド(riscv64)
=============================

大体手順としては、arm64に準じる。

```plaintext
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic main restricted
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-updates main restricted
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic universe
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-updates universe
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic multiverse
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-updates multiverse
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-backports main restricted universe multiverse
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-security main restricted
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-security universe
deb [arch=arm64,armhf,riscv64] http://ports.ubuntu.com/ubuntu-ports mantic-security multiverse
```


ただ、toolchainファイルがなんか調子悪いので、手修正

<details><summary>修正詳細はココ</summary>

```diff_c_make
diff --git a/platforms/linux/riscv-gnu.toolchain.cmake b/platforms/linux/riscv-gnu.toolchain.cmake
index 1657bd1681..6b61251762 100644
--- a/platforms/linux/riscv-gnu.toolchain.cmake
+++ b/platforms/linux/riscv-gnu.toolchain.cmake
@@ -17,18 +17,18 @@ if(NOT "x${GCC_COMPILER_VERSION}" STREQUAL "x")
 endif()

 if(NOT DEFINED GNU_MACHINE)
-  set(GNU_MACHINE riscv64-unknown-linux-gnu CACHE STRING "GNU compiler triple")
+  set(GNU_MACHINE riscv64-linux-gnu CACHE STRING "GNU compiler triple")
 endif()

 if(NOT DEFINED TOOLCHAIN_COMPILER_LOCATION_HINT)
   set(TOOLCHAIN_COMPILER_LOCATION_HINT PATHS /opt/riscv/bin ENV PATH)
 endif()

-if(NOT DEFINED CMAKE_C_COMPILER)
-  find_program(CMAKE_C_COMPILER NAMES ${GNU_MACHINE}-gcc${__GCC_VER_SUFFIX} PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
-else()
-  #message(WARNING "CMAKE_C_COMPILER=${CMAKE_C_COMPILER} is defined")
-endif()
+# if(NOT DEFINED CMAKE_C_COMPILER)
+#  find_program(CMAKE_C_COMPILER NAMES ${GNU_MACHINE}-gcc${__GCC_VER_SUFFIX} PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
+# else()
+#   #message(WARNING "CMAKE_C_COMPILER=${CMAKE_C_COMPILER} is defined")
+# endif()
 if(NOT DEFINED CMAKE_CXX_COMPILER)
   find_program(CMAKE_CXX_COMPILER NAMES ${GNU_MACHINE}-g++${__GCC_VER_SUFFIX} PATHS ${TOOLCHAIN_COMPILER_LOCATION_HINT})
 else()
@@ -45,11 +45,11 @@ else()
   #message(WARNING "CMAKE_AR=${CMAKE_AR} is defined")
 endif()

-if(NOT DEFINED RISCV_SYSROOT)
-  get_filename_component(_base_dir ${CMAKE_C_COMPILER} DIRECTORY)
-  get_filename_component(_base_dir ${_base_dir} DIRECTORY)
-  set(RISCV_SYSROOT ${_base_dir}/sysroot CACHE PATH "RISC-V sysroot")
-endif()
+# if(NOT DEFINED RISCV_SYSROOT)
+#  get_filename_component(_base_dir ${CMAKE_C_COMPILER} DIRECTORY)
+#  get_filename_component(_base_dir ${_base_dir} DIRECTORY)
+#   set(RISCV_SYSROOT ${_base_dir}/sysroot CACHE PATH "RISC-V sysroot")
+# endif()

 set(CMAKE_SYSROOT "${RISCV_SYSROOT}")
 set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${RISCV_SYSROOT})
 
```
</details>

それでは順番にビルドしていく。

```bash
sudo apt install libfreetype-dev:riscv64 libharfbuzz-dev:riscv64
 
PKG_CONFIG_PATH=/usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/riscv64-linux-gnu \
    PKG_CONFIG_SYSROOT_DIR=/ \
       pkg-config freetype2 harfbuzz --cflags --libs
(output) -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/riscv64-linux-gnu/glib-2.0/include -L/usr/lib/riscv64-linux-gnu -lfreetype -lharfbuzz

PKG_CONFIG_PATH=/usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig \
    PKG_CONFIG_LIBDIR=/usr/lib/riscv64-linux-gnu \
    PKG_CONFIG_SYSROOT_DIR=/ \
        cmake -S opencv \
              -B build4-full_riscv64 \
              -DCMAKE_C_COMPILER=/usr/bin/riscv64-linux-gnu-gcc \
              -DCMAKE_CXX_COMPILER=/usr/bin/riscv64-linux-gnu-g++ \
              -DRISCV_SYSROOT=/ \
              -DCMAKE_TOOLCHAIN_FILE=/home/kmtr/work/opencv/platforms/linux/riscv64-gcc.toolchain.cmake \
              -DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules \
              -GNinja
 
cmake      --build   build4-full_riscv64
sudo cmake --install build4-full_riscv64
```

■ まとめ: Multiarchでクロスビルドが簡単に！
=========================================

これで、x86-64 Host１つあれば、ARMv7/ARMv8/RISCV用のOpenCVが作れるようになりますね！

- Ubuntuには、Multiarchという仕組みがあり、異アーキテクチャを混在できる。
- OpenCVのクロスビルドに使うと、他Archのバイナリが簡単に作れる。


以上です。ありがとうございました。