OpenCV 4.12.0
開源計算機視覺
載入中...
搜尋中...
無匹配項
使用 Ubuntu/Debian 進行 MultiArch 交叉編譯

上一個教程: 基於 ARM 的 Linux 系統的交叉編譯
下一個教程: 使用 CUDA 為 Tegra 構建 OpenCV

原始作者Kumataro
相容性Ubuntu >=23.04
OpenCV >=4.8.0
警告
本教程可能包含過時資訊。

什麼是 "MultiArch"

OpenCV 可能會使用許多第三方庫來處理影片和影像解碼、渲染、加速和複雜的數學演算法。這些第三方元件由 CMake 在構建主機上查詢。交叉編譯允許為異構架構或作業系統構建 OpenCV,但我們會失去龐大的元件支援,必須單獨交叉編譯每個依賴項並在 OpenCV 構建期間指向它們。

Debian/Ubuntu MultiArch 有助於解決此問題。它允許在宿主機系統上安裝多種異構架構庫,並在 OpenCV 依賴項解析期間使用它們。

警告
  • 遵循這些步驟會使您的 Linux 環境變得有些“髒亂”。如果可能,最好使用虛擬機器 (VM) 或容器(例如 Docker)。
  • 本教程假設宿主機和目標機使用相同的 Ubuntu 版本。請勿為外部庫依賴項使用/混合不同版本。
    • 正確:宿主機和目標機均為 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 - 請替換為您的賬戶名。
+ work
+ opencv - 原始碼,從 github 克隆
+ opencv_contrib - 原始碼,從 github 克隆
+ build4-full_arm64 - 生成檔案(用於 aarch64 目標),由 cmake 建立
+ build4-full_armhf - 生成檔案(用於 armhf 目標),由 cmake 建立
  1. 在您的主目錄下建立工作資料夾。
  2. 從倉庫克隆 OpenCV 和 OpenCV Contrib 到 work 目錄。
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 設定

這些步驟在宿主機上執行。

aptdpkg 是 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

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 - arm64 的共享庫
+ pkgconfig - arm64 庫的 pkg-config 檔案
+ arm-linux-gnueabihf - armhf 的共享庫
+ pkgconfig - armhf 庫的 pkg-config 檔案
+ share
+ pkgconfig - pkg-config 檔案(用於標頭檔案)

使用 PKG_CONFIG_PATHPKG_CONFIG_LIBDIRPKG_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. 在宿主機上為目標安裝外部庫

此步驟在宿主機上執行。

在宿主機 (x86-64) 上為目標機 (arm64) 安裝 libfreetype-dev、libharfbuzz-dev 和 FFmpeg 包。

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
注意
最後,需要 "python3.XX" 字串。因此此指令碼會生成它。
  • 從 "/usr/bin/python3" 獲取真實路徑到 "/usr/bin/python3.xx"。
  • 從 "/usr/bin/python3.xx" 獲取基本名稱到 "pyhton3.xx"。

以下是 cmake 輸出。

  • HostLinux x86_64
  • TargetLinux 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/ (版本未定義 - 由於交叉編譯無法探測)
-- 安裝路徑: lib/python3.11/dist-packages/cv2/python-3.11
--
-- Python(用於構建): /usr/bin/python3.11
--

步驟 3. 構建並打包 OpenCV 庫和標頭檔案

此步驟在宿主機上執行。

構建並安裝。(此處的 install 僅表示將生成檔案複製到 install 資料夾。)

cmake --build build4-full_arm64
sudo cmake --install build4-full_arm64

tar czvf opencv_arm64.tgz -C build4-full_arm64/install .

並將 opencv_arm64.tgz 傳送到目標機。

步驟 4. 在目標機上安裝依賴庫

此步驟在目標系統上執行。

在目標機上為 OpenCV/OpenCV contrib 庫安裝依賴執行時庫。

libavcodec60 \

sudo apt install -y \
libavformat60 \
libavutil58 \
libswscale7 \
libfreetype6 \
libharfbuzz0b
如果執行時庫和/或程式的版本增加,apt 包名稱可能會更改(例如 Ubuntu 23.04 使用 libswscale6,但 Ubuntu 23.10 使用 libswscale7)。請使用 apt search 命令或 https://packages.ubuntu.com/ 查詢。
sudo ldconfig

如果您想啟用 Python 3 封裝,也請安裝這些包。

sudo apt install -y \
python3-minimal \
python3-numpy
警告
宿主機和目標機之間的外部庫版本應相同。請儘可能同時更新到最新版本的庫。
警告

即使宿主機和目標機之間的作業系統版本相同,由於庫的額外更新,版本可能有所不同。這將導致意外問題。

例如)

在宿主機上,OpenCV 已使用外部 libA (v1.0) 為目標機構建。

  • libA (v1.1) 可能會更新。
  • 在目標機上,libA (v1.1) 已安裝以使用 OpenCV。
  • 在這種情況下,libA 的版本在編譯和執行之間存在差異。
  • 如果您忘記/未能正確安裝某些必要的庫,OpenCV 將無法正常工作。
警告

ldd 命令可以檢測依賴項。如果有任何“未找到”,請安裝必要的庫。

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 所需的所有庫都已安裝。
:

libharfbuzz.so.0 => /lib/aarch64-linux-gnu/libharfbuzz.so.0 (0xABCDEF001234567)

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
步驟 5. 將 OpenCV 庫安裝到目標機
(正確)freetype modules 所需的所有庫都已安裝。
:

此步驟在目標機上執行。

從宿主機接收 opencv_arm64.tgz(在步驟 3 生成),並解壓到 /usr/local

sudo tar zxvf opencv_arm64.tgz -C /usr/local

您可以像自主編譯一樣使用 OpenCV 庫。以下是 OpenCV 示例程式碼。在目標機上編譯並執行它。
sudo ldconfig

Makefile

a.out : main.cpp

g++ main.cpp -o a.out \
-I/usr/local/include/opencv4 \
-lopencv_core
main.cpp

#include <opencv2/core.hpp>

#include <iostream>
int main(void)
std::cout << cv::getBuildInformation() << std::endl;
{
const String & getBuildInformation()
return 0;
}
執行 make 並執行它。
返回完整的配置時 cmake 輸出。
int main(int argc, char *argv[])
定義 highgui_qt.cpp:3

make a.out

./a.out
如果您想啟用 Python 3 封裝,請執行以下命令進行確認。

python3 -c "import cv2; print(cv2.getBuildInformation())"

為 armv7 進行交叉編譯

以下是在宿主機 (x86-64) 上為目標機 (armhf) 進行編譯的步驟。

為了解決依賴項,linux-libc-dev:armhf 是必需的。

  • 為了使用 neon 進行最佳化,-DENABLE_NEON=ON 是必需的。
  • linux-libc-dev:armhf \
sudo apt install -y \
libavcodec-dev:armhf \
libavformat-dev:armhf \
libavutil-dev:armhf \
libswscale-dev:armhf \
libfreetype-dev:armhf \
libharfbuzz-dev:armhf
-B build4-full_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 \
-DENABLE_NEON=ON \
-DCMAKE_TOOLCHAIN_FILE=/home/kmtr/work/opencv/platforms/linux/arm-gnueabi.toolchain.cmake \
cmake --build build4-full_armhf
-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules \
-GNinja
sudo cmake --install build4-full_armhf
tar czvf opencv_armhf.tgz -C build4-full_armhf/install .
TargetLinux arm

以下是 cmake 輸出。

  • HostLinux x86_64
  • -- Timestamp: 2023-12-02T03:39:58Z
  • 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
-- Target: Linux 1 arm
-- Host: Linux 6.5.0-13-generic x86_64
-- 基線: NEON
-- CMake: 3.27.4
-- CMake generator: Ninja
-- CMake build tool: /usr/bin/ninja
-- Configuration: Release
--
-- CPU/HW features
-- 請求: DETECT
-- C++ Compiler: /usr/bin/arm-linux-gnueabihf-g++ (ver 13.2.0)
-- required: NEON
-- disabled: VFPV3
--
-- C/C++
-- Built as dynamic libs?: YES
-- C++ standard: 11
於 2025 年 7 月 3 日星期四 12:14:35 為 OpenCV 生成,由 doxygen 1.12.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)
--