前のチュートリアル: ARM ベースの Linux システム向けのクロスコンパイル
次のチュートリアル: CUDA を用いた Tegra 向け OpenCV のビルド
| |
| 原著者 | Kumataro |
| 互換性 | Ubuntu >=23.04 |
| OpenCV >=4.8.0 |
- 警告
- このチュートリアルには古い情報が含まれている可能性がある。
"MultiArch" とは何か
OpenCV は、動画や画像のデコード、レンダリング、アクセラレーション、複雑な数学アルゴリズムのために多くのサードパーティライブラリを利用することがある。これらのサードパーティコンポーネントはビルドホスト上の CMake によって検出される。クロスコンパイルでは、別のアーキテクチャや OS 向けに OpenCV をビルドできるが、その豊富なコンポーネント群が使えなくなり、各依存ライブラリを個別にクロスコンパイルし、OpenCV のビルド時にそれを指定しなければならない。
Debian/Ubuntu の MultiArch はこの問題の解決に役立つ。これにより、複数の別アーキテクチャ向けライブラリをホストシステムにインストールし、OpenCV の依存関係解決時にそれらを利用できるようになる。
- 警告
- これらの手順を実行すると、Linux 環境が少し汚れることになる。可能であれば、VM やコンテナ (例: Docker) を使う方がよい。
- This tutorial expects host and target uses same Ubuntu version. Do not use/mix different versions for external library dependency.
- 良い例: ホストとターゲットがどちらも 23.04 である。
- 良い例: ホストとターゲットがどちらも 23.10 である。
- 良くない例: ホストが 23.04 で、ターゲットが 23.10 である。
- 良くない例: ホストが 23.10 で、ターゲットが 23.04 である。
- このチュートリアルは、Debian および Raspberry Pi OS のようなその派生ディストリビューションでも利用できる。必要に応じて適宜変更すること。
ツールのダウンロード
クロスコンパイルに必要なツールとツールチェーンをインストールする。
- 基本的に git、cmake、pkgconf、build-essential が必要である。
- ninja-build はコンパイル時間を短縮するためのものである (省略可能)。
- crossbuild-essential-armhf は armv7 ターゲット向けのツールチェーンパッケージである。
- crossbuild-essential-arm64 は aarch64 ターゲット向けのツールチェーンパッケージである。
sudo apt update -y
sudo apt install -y \
git \
cmake \
pkgconf \
build-essential \
ninja-build \
crossbuild-essential-armhf \
crossbuild-essential-arm64
Python 3 ラッパーを有効にしたい場合は、これらのパッケージもインストールする。
sudo apt install -y \
python3-minimal \
python3-numpy
作業フォルダの構成
このチュートリアルでは、次の作業フォルダ構成を使用する。
/home
+ kmtr - please replace your account name.
+ work
+ opencv - source, cloned from github
+ opencv_contrib - source, cloned from github
+ build4-full_arm64 - artifact(for aarch64 target), created by cmake
+ build4-full_armhf - artifact(for armhf target), created by cmake
- ホームディレクトリの下に作業フォルダを作成する。
- OpenCV と OpenCV Contrib をリポジトリから作業ディレクトリにクローンする。
cd ~
mkdir work
cd work
git clone --depth=1 https://github.com/opencv/opencv.git
git clone --depth=1 https://github.com/opencv/opencv_contrib.git
apt と dpkg の設定を更新する
これらの手順はホスト上で行う。
apt と dpkg は、Ubuntu と Debian で使われるパッケージ管理システムである。
以下は MultiArch を使うためのセットアップ手順である。
ステップ 1. arm64 と armhf 用の apt ソースを追加する
sudo apt edit-sources を実行して、ファイルの末尾に別アーキテクチャ向けライブラリを追加する。
例 1: Ubuntu 23.04 向けの arm64 と armv7
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
例 2: Ubuntu 23.10 向けの arm64 と armv7
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
ステップ 2. apt データベースを更新する
新しい apt ソースを反映するために apt データベースを更新する。
sudo apt update を実行する。
ステップ 3. dpkg 設定を更新する
別のアーキテクチャをサポートするために dpkg 設定を更新する。
sudo dpkg --add-architecture arm64 および/または sudo dpkg --add-architecture armhf を実行する。
sudo dpkg --add-architecture arm64
sudo dpkg --add-architecture armhf
sudo dpkg --print-architecture はホストのアーキテクチャを表示する。
sudo dpkg --print-architecture
amd64
そして sudo dpkg --print-foreign-architectures はサポートされている別アーキテクチャを表示する。
sudo dpkg --print-foreign-architectures
arm64
armhf
pkg-config の動作を確認する
MultiArch では、各アーキテクチャ向けの複数の共有ライブラリと pkg-config 情報が /usr/lib に格納される。
/usr
+ lib
+ aarch64-linux-gnu - shared libraries for arm64
+ pkgconfig - pkg-config files for arm64 libraries
+ arm-linux-gnueabihf - shared libraries for armhf
+ pkgconfig - pkg-config files for armhf libraries
+ share
+ pkgconfig - pkg-config files(for header files)
PKG_CONFIG_PATH、PKG_CONFIG_LIBDIR、PKG_CONFIG_SYSROOT_DIR オプションを用いて pkg-config が動作することを確認する。
aarch64 の場合:
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
armv7 の場合:
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
aarch64 向けのクロスコンパイル
以下は、ホスト (x86-64) でターゲット (aarch64) 向けにコンパイルする手順である。
ステップ 1. ターゲット用の外部ライブラリをホストにインストールする
この手順はホスト上で行う。
ターゲット (arm64) 向けの libfreetype-dev、libharfbuzz-dev、FFmpeg パッケージをホスト (x86-64) にインストールする。
sudo apt install -y \
libavcodec-dev:arm64 \
libavformat-dev:arm64 \
libavutil-dev:arm64 \
libswscale-dev:arm64 \
libfreetype-dev:arm64 \
libharfbuzz-dev:arm64
Python 3 ラッパーを有効にしたい場合は、これらのパッケージもインストールする。
sudo apt install -y \
libpython3-dev:arm64
成功すれば、pkg-config はこれらのパッケージに関する情報を表示できる。
Freetype2 と Harfbuzz の場合:
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
FFmpeg の場合:
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 libavcodec libavformat libavutil libswscale --cflags --libs
-I/usr/include/aarch64-linux-gnu -L/usr/lib/aarch64-linux-gnu -lavcodec -lavformat -lavutil -lswscale
ステップ 2. OpenCV の設定を構成する
この手順はホスト上で行う。
cmake を実行して aarch64 向けのクロスコンパイル設定を作成する。
- 覚え書き
-DCMAKE_TOOLCHAIN_FILE は相対パスではなく、絶対パス/実パスである必要がある。
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
Python 3 ラッパーを有効にしたい場合は、追加のオプションが必要である。
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
- 覚え書き
- Lastly, "python3.XX" string is needed. So this script generate it.
- "/usr/bin/python3" から "/usr/bin/python3.xx" への実パスを取得する。
- "/usr/bin/python3.xx" から "pyhton3.xx" のようにベース名を取得する。
以下はcmakeの出力である。
HostはLinux x86_64である。
TargetはLinux aarch64である。
- FFmpegが利用可能である。
-- General configuration for OpenCV 4.8.0-dev =====================================
-- Version control: 408730b
--
-- Extra modules:
-- Location (extra): /home/kmtr/work/opencv_contrib/modules
-- Version control (extra): faa5468
--
-- Platform:
-- Timestamp: 2023-12-01T22:02:14Z
-- Host: Linux 6.5.0-13-generic x86_64
-- Target: Linux 1 aarch64
-- CMake: 3.27.4
-- CMake generator: Ninja
-- CMake build tool: /usr/bin/ninja
-- Configuration: Release
--
-- CPU/HW features:
-- Baseline: NEON FP16
-- required: NEON
-- disabled: VFPV3
-- Dispatched code generation: NEON_DOTPROD NEON_FP16 NEON_BF16
-- requested: NEON_FP16 NEON_BF16 NEON_DOTPROD
-- NEON_DOTPROD (1 files): + NEON_DOTPROD
-- NEON_FP16 (2 files): + NEON_FP16
-- NEON_BF16 (0 files): + NEON_BF16
--
-- C/C++:
-- Built as dynamic libs?: YES
-- C++ standard: 11
-- C++ Compiler: /usr/bin/aarch64-linux-gnu-g++ (ver 13.2.0)
:
:
--
-- 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 3ラッパーの有効化に成功すると、Python 3:セクションにより多くの情報が表示される。
--
-- 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
--
ステップ3. OpenCVのライブラリとヘッダをビルドしてアーカイブする
このステップはホスト上で行う。
ビルドしてインストールする。(ここでのinstallは、成果物をinstallフォルダにコピーするだけのことを意味する。)
cmake --build build4-full_arm64
sudo cmake --install build4-full_arm64
成果物(ビルドしたライブラリとヘッダ)をtarコマンドでopencv_arm64.tgzにアーカイブする。
tar czvf opencv_arm64.tgz -C build4-full_arm64/install .
そしてopencv_arm64.tgzをターゲットに送る。
ステップ4. ターゲットに依存ライブラリをインストールする
このステップはターゲットシステム上で実行する。
ターゲットにOpenCV/OpenCV contribライブラリ用のランタイム依存ライブラリをインストールする。
sudo apt install -y \
libavcodec60 \
libavformat60 \
libavutil58 \
libswscale7 \
libfreetype6 \
libharfbuzz0b
sudo ldconfig
Python 3 ラッパーを有効にしたい場合は、これらのパッケージもインストールする。
sudo apt install -y \
python3-minimal \
python3-numpy
- 警告
- ランタイムライブラリやプログラムのバージョンが上がると、aptパッケージ名が変わる場合がある(例えば
libswscale6はUbuntu 23.04で使われるが、libswscale7はUbuntu 23.10で使われる)。apt searchコマンドやhttps://packages.ubuntu.com/ で探すこと。
- 警告
ホストとターゲットの外部ライブラリのバージョンは同じであるべきである。可能な限り同時に最新バージョンのライブラリへ更新すること。
ホストとターゲットでOSのバージョンが同じであっても、ライブラリの追加更新によってバージョンが異なる場合がある。これは予期しない問題を引き起こす。
例えば)
- ホスト上で、OpenCVは外部ライブラリlibA (v1.0)を用いてターゲット向けにビルドされている。
- libA (v1.1)に更新されることがある。
- ターゲット上では、OpenCVを使うためにlibA (v1.1)がインストールされる。
- この場合、コンパイル時と実行時とでlibAのバージョンが異なる。
- 警告
必要なライブラリのインストールを忘れたり、不一致があったりすると、OpenCVは正しく動作しない。
lddコマンドで依存関係を検出できる。"not found"があれば、必要なライブラリをインストールすること。
ldd /usr/local/lib/libopencv_freetype.so
(良くない例)freetype moduleはlibharfbuzz.so.0を必要とするが、まだインストールされていない。
linux-vdso.so.1 (0xABCDEFG01234567)
libopencv_imgproc.so.408 => /usr/local/lib/libopencv_imgproc.so.408 (0xABCDEF001234567)
libfreetype.so.6 => /lib/aarch64-linux-gnu/libfreetype.so.6 (0xABCDEF001234567)
libharfbuzz.so.0 => not found
libopencv_core.so.408 => /usr/local/lib/libopencv_core.so.408 (0xABCDEF001234567)
:
(良い例)freetype modulesが必要とするすべてのライブラリがインストールされている。
linux-vdso.so.1 (0xABCDEFG01234567)
libopencv_imgproc.so.408 => /usr/local/lib/libopencv_imgproc.so.408 (0xABCDEF001234567)
libfreetype.so.6 => /lib/aarch64-linux-gnu/libfreetype.so.6 (0xABCDEF001234567)
libharfbuzz.so.0 => /lib/aarch64-linux-gnu/libharfbuzz.so.0 (0xABCDEF001234567)
libopencv_core.so.408 => /usr/local/lib/libopencv_core.so.408 (0xABCDEF001234567)
:
ステップ5. ターゲットにOpenCVライブラリをインストールする
このステップはターゲット上で行う。
ホストからopencv_arm64.tgz(ステップ3で生成したもの)を受け取り、/usr/localに展開する。
sudo tar zxvf opencv_arm64.tgz -C /usr/local
sudo ldconfig
セルフコンパイルの場合と同じようにOpenCVライブラリを使用できる。以下はOpenCVのサンプルコードである。ターゲット上でコンパイルして実行する。
Makefile
a.out : main.cpp
g++ main.cpp -o a.out \
-I/usr/local/include/opencv4 \
-lopencv_core
main.cpp
#include <iostream>
{
return 0;
}
const String & getBuildInformation()
Returns full configuration time cmake output.
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
makeを実行して動かす。
Python 3ラッパーを有効にしたい場合は、以下のコマンドを実行して確認する。
python3 -c "import cv2; print(cv2.getBuildInformation())"
armv7向けのクロスコンパイル
以下はホスト(x86-64)上でターゲット(armhf)向けにコンパイルする方法である。
- 依存関係を解決するために、
linux-libc-dev:armhfが必要である。
- neonで最適化するには、
-DENABLE_NEON=ONが必要である。
sudo apt install -y \
linux-libc-dev:armhf \
libavcodec-dev:armhf \
libavformat-dev:armhf \
libavutil-dev:armhf \
libswscale-dev:armhf \
libfreetype-dev:armhf \
libharfbuzz-dev: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=/ \
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
tar czvf opencv_armhf.tgz -C build4-full_armhf/install .
以下はcmakeの出力である。
HostはLinux x86_64である。
TargetはLinux armである。
- FFmpegが利用可能である。
-- General configuration for OpenCV 4.8.0-dev =====================================
-- Version control: 408730b
--
-- Extra modules:
-- Location (extra): /home/kmtr/work/opencv_contrib/modules
-- Version control (extra): faa5468
--
-- Platform:
-- Timestamp: 2023-12-02T03:39:58Z
-- Host: Linux 6.5.0-13-generic x86_64
-- Target: Linux 1 arm
-- CMake: 3.27.4
-- CMake generator: Ninja
-- CMake build tool: /usr/bin/ninja
-- Configuration: Release
--
-- CPU/HW features:
-- Baseline: NEON
-- requested: DETECT
-- required: NEON
-- disabled: VFPV3
--
-- C/C++:
-- Built as dynamic libs?: YES
-- C++ standard: 11
-- C++ Compiler: /usr/bin/arm-linux-gnueabihf-g++ (ver 13.2.0)
:
:
--
-- 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)
--