目錄
一、常見問題
二、OpenCV交叉編譯
三、補充說明
1. pkgconfig配置(非必須)
2. CMakeLists.txt檔案使用opencv
3. 配置目标平台運作可執行程式時opencv動态庫搜尋路徑
主機環境:Ubuntu 18.04.6 LTS,x86_64
目标平台:Qualcomm apq8096,AArch64
CMake版本:3.10.2
OpenCV版本:https://github.com/opencv/opencv (4.5.3)
一、常見問題
1. The c/c++ compiler is not able to compile a simple test program.
如果在PC上将交叉編譯環境配置正确,該問題其實一般不會遇到。若遇到可通過設定CMAKE_SYSROOT來解決(該變量與标志“--sysroot”對應),設定值是交叉編譯工具鍊root目錄,參見第二節Step2。
注意:CMAKE_SYSROOT據說在cmake3.0及以上版本才支援!
2. 提示警告“CMAKE_SYSTEM_PROCESSOR is not defined”。以及make後,編譯過程出現某個子產品不通過。這兩類問題其實就是一個問題,筆者将在本文第二節Step3指出規避方案。
二、OpenCV交叉編譯
借助cmake-gui,本節将交叉編譯過程分為六個步驟進行詳細介紹。
Step1: 指定建構目錄
Step2: 設定CMAKE_SYSROOT(一般不需要,若出現上一節問題1時就需要手動設定)
筆者交叉編譯工具鍊目錄結構:
Step3: 指定CMAKE_TOOLCHAIN_FILE
該步驟很重要,而且必須在點選Configure之前配置(詳見以下官方介紹)。一般編譯過程出現某些子產品不通過就是因為缺少該環節,以及提示警告“CMAKE_SYSTEM_PROCESSOR is not defined”也是缺少該環節。
CMAKE_TOOLCHAIN_FILE: This variable is specified on the command line when cross-compiling with CMake. It is the path to a file which is read early in the CMake run and which specifies locations for compilers and toolchain utilities, and other target platform and compiler related information.
基于筆者目标機器的交叉編譯環境,筆者選擇的是如下cmake檔案:
在opencv根目錄platforms子目錄下存放有android、apple、ios、Linux等平台的cmake檔案。
Step4: 指定toolchain
然後根據個人PC所配置的交叉編譯工具鍊,将下圖所示幾個框完善:
提示1:opencv對CPU Platforms的定義如下(ARM - ARM CPU, not defined for AArch64):
提示2:Compilers一般在交叉編譯工具鍊根目錄的bin子目錄裡面(筆者本文所使用交叉工具鍊的目錄結構與此稍有差別),如下:
Step5: 修改編譯配置
上一步完成後,CMake-GUI底部輸出若幹建構資訊,可看到最終的安裝位置、Release(預設)還是Debug版本、動态庫(預設)還是靜态庫、FLAGS配置 等等。若需要修改,可勾選上下圖箭頭所指Advanced項(同時可點選一下Configure,因為有參數供選擇的變量,未點選過Configure時參數不會擴充顯示出來供選擇)。
比較重要的是如下變量的配置(Debug對應Debug,Release對應Release,Debug版本庫大小一般在200MB左右。NEON的加速性能若想展現出來,編譯優化選項至少開到O2):
然後點選Configure,會發現CMake-GUI底部輸出有紅色字元串(交叉編譯工具鍊不同,稍有差别),遇到這種情況一般是未勾選子產品對應變量(根據工程需要決定是否勾選,不勾選編譯一般也不會報錯。不過每次建構opencv庫耗時不短,建議多多益善)。
對于opencv,以下幾個子產品是運作強依賴的(預設也是勾選上的):
最後,點選Generate,并仔細檢查CMake-GUI底部輸出資訊是否與自己所配置的一緻,若一切正常則就可以關閉CMake-GUI。
Step6: make和install
安裝目錄結構(動态庫版本隻需将lib目錄拷貝到目标機器即可):
三、補充說明
1. pkgconfig配置(非必須)
opencv庫安裝後,在安裝目錄會有四個子目錄,進入lib目錄,然後建立目錄pkgconfig,并在裡面建立檔案opencv4.pc,其内容可參考如下:
prefix=/home/slf/Works/opencv-lib/opencv453-apq8096/shared #opencv安裝根目錄
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv4/opencv2
includedir_new=${prefix}/include/opencv4
Name: OpenCV
Description: Open Source Computer Vision Library shared
Version: 4.5.3
Libs: -L${exec_prefix}/lib
Libs.private: -lm -lpthread
Cflags: -I${includedir_old} -I${includedir_new}
然後進入/etc目錄打開檔案profile檔案,按照下圖所示格式加入剛建立opencv4.pc檔案所在路徑(注意是給環境變量PKG_CONFIG_PATH追加字元串):
重新開機電腦後該設定将永久有效。若不想重新開機而是臨時使用,可以在終端指令行執行以下指令(但也僅限目前終端有效):
source /etc/profile
echo $PKG_CONFIG_PATH #檢視設定是否有效
如此設定後在指令行即可直接通過pkg-config連結opencv庫。不過當PC安裝有多個版本的opencv庫時,實際意義就不大了。
2. CMakeLists.txt檔案使用opencv
法一:FIND_PACKAGE()
如果PC隻安裝一個版本的opencv,一般直接使用以下指令即可:
FIND_PACKAGE(OpenCV REQUIRED)
若PC上安裝有多個版本的opencv,則在FIND_PACGAGE()之前還需設定路徑:
SET(CMAKE_PREFIX_PATH "/home/slf/Works/opencv-lib/opencv453-apq8096/shared")
FIND_PACKAGE(OpenCV REQUIRED)
法二:FILE()
#靜态庫就将.so替換為.a
FILE(GLOB_RECURSE OpenCV_LIBS /home/slf/Works/opencv-lib/opencv453-apq8096/shared/lib/*.so*)
SET(OpenCV_INCLUDE_DIRS
/home/slf/Works/opencv-lib/opencv453-apq8096/shared/include
/home/slf/Works/opencv-lib/opencv453-apq8096/shared/include/opencv4)
提示:個人建議使用法二。因為當PC安裝有多個版本時,項目工程目錄恰也有多個CMakeLists.txt檔案,且不同檔案使用的opencv版本不一緻,則法一可能出現多個檔案最終均是使用的同一個opencv版本。此外,無論哪種方法,都應考慮規避循環依賴:
SET(LINK_LIBS
-Wl,--start-group # to resolve the circle dependency
${OpenCV_LIBS}
pthread
m
dl
-Wl,--end-group)
3. 配置目标平台運作可執行程式時opencv動态庫搜尋路徑
在/etc/ld.so.conf.d/目錄下建立一個任意命名但以conf為字尾的檔案,檔案内容是opencv庫檔案所在路徑。檔案儲存後在終端指令行執行ldconfig即可。
鄭重提示:①對文中描述不清之處,可以評論區留言,筆者看到後會第一時間回複!
②轉載注明出處,就是對筆者最大的支援!