這個交叉編譯折磨了我好幾天,剛剛實踐成功,迫不及待的跟大家分享一下,希望對你有用哦。
操作環境:Ubuntu 14.04
編譯器:arm-linux-guneabi-gcc
Cmake版本:2.8.12.2
Cmake-gui:版本與cmake相同
目標主機:T717
Opencv版本:3.1.0
依賴庫版本:
Libz:zlib-1.2.11 下載網址:https://sourceforge.net/projects/libpng/files/zlib/1.2.11/zlib-1.2.11.tar.gz/download?use_mirror=nchc&download=
Libx264:x264-snapshot-20191124-2245
下載網址:http://www.videolan.org/developers/x264.html
Libxvid:xvidcore-1.3.5
下載網址:https://labs.xvid.com/source/
Ffmpeg:ffmpeg-4.2.1
下載網址:http://ffmpeg.org/download.html
一、安裝依賴項
在終端依次執行以下操作:
(1)安裝pkg-config
sudo apt-get install pkg-config
sudo apt-get install libgtk2.0-dev
(2)安裝依賴項
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
這幾項與視頻解碼相關,不安裝的話後面 opencv make時會出現下圖情況:
參考:https://my.oschina.net/u/1250206/blog/850302
二、安裝依賴庫
(1)目標主機安裝目錄構建
移植opencv其實不難,重點在於弄清安裝路徑和編譯器,只要不和本地opencv弄混,理論上來講就沒問題了。我們首先在開發主機上構建一個臨時安裝環境,便於交叉編譯過程依賴庫的搜索以及方便最後向目標主機轉移安裝,還有最重要的一點就是防止與開發主機環境弄混。終端執行:
cd home/xlb/opt/ #這裏的xlb是我的用戶名
mkdir arm
本文的安裝目錄是home文件夾下的opt文件夾,注意與系統目錄下的opt文件夾區分開。將前文所提到的依賴庫和opencv源碼解壓到opt文件夾下,接下來先對依賴庫進行交叉編譯並安裝到臨時安裝目錄opt/arm下。
(2)交叉編譯libz
cd /home/xlb/zlib-1.2.11 #進入zlib源碼目錄
./configure --prefix=/home/xlb/opt/arm --shared #prefix參數指定了臨時安裝目錄
配置完成後會生成makefile文件,需要對makefile文件進行修改,適配交叉編譯工具鏈。
終端執行:
gedit Makefile #用編輯器打開Makefile文件並進行以下對應部分的修改
CC = arm-linux-gnueabi-gcc #交叉編譯工具鏈
AR = arm-linux-gnueabi-ar
RANLIB = arm-linux-gnueabi-ranlib
LDSHARED = arm-linux-gnueabi-gcc -shared -wl, -soname,libz.so.1,--version-script,zlib.map
修改完成後,保存,下一步進行編譯和安裝。終端執行:
make
make install
可能出現的錯誤:
xlb@xlb-VirtualBox:~/opt/zlib-1.2.11$ make
arm-linux-gnueabi-gcc -O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o example.o test/example.c
make: arm-linux-gnueabi-gcc: Command not found
make: *** [example.o] Error 127
解決辦法:
需要把交叉編譯器所在的目錄加到環境變量中,在終端執行:
sudo –s
cd etc
gedit profile
打開profile文件後,添加export PATH=$PATH:/home/user/linux/bin,冒號後是交叉編譯工具arm-linux-gnueabi-gcc所在目錄。修改完成後保存並關閉。
終端執行以下命令使環境變量修改立即生效:
source /etc/profile/
參考:https://blog.csdn.net/polarisyj86/article/details/89395083
(2)交叉編譯libx264
在終端執行以下命令:
cd /home/xlb/opt/ x264-snapshot-20191124-2245
CC=arm-linux-gnueabi-gcc ./configure --enable-shared --host=arm-linux-gnueabi --disable-asm --prefix=/home/xlb/opt/arm
沒有錯誤的話,繼續執行:
make
make install
(3)交叉編譯libxvid
在終端依次執行:
cd /home/xlb/opt/ xvidcore-1.3.5
cd build/generic #切換到編譯腳本所在的目錄
./configure --prefix=/home/xlb/opt/arm --host=arm-linux-gnueabi --disable-assembly
如果看到一堆yes說明配置沒有問題,繼續執行:
make
make install
(4)交叉編譯ffmpeg
在終端執行:
cd /home/xlb/opt/ffmpeg-4.2.1
./configure --prefix=/home/xlb/opt/arm --enable-shared --disable-static --enable-gpl --enable-cross-compile --arch=arm --disable-stripping --target-os=linux --enable-libx264 --enable-libxvid --cc=arm-linux-gnueabi-gcc --enable-swscale --extra-cflags=-I/home/xlb/opt/arm/include/ --extra-ldflags=-L/home/xlb/opt/arm/lib/
注意,刷最後兩句是前面三個依賴庫的安裝目錄,如果不加上可能會報libx264 not found錯誤。
到這裏如果沒有報錯,就可以進行編譯安裝了,終端執行:
make
make install
三、交叉編譯opencv
(1)設置工具鏈toolchain.cmake
在用cmake編譯之前首先要構建工具鏈cmake文件,在終端執行:
cd home/xlb/opt
cd opencv-3.1.0/
mkdir arm-build
cd ./arm-build
gedit toolchain.cmake
在打開的toolchain.cmake文件中添加以下內容:
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR arm )
set( CMAKE_C_COMPILER arm-linux-gnueabi-gcc )
set( CMAKE_CXX_COMPILER arm-linux-gnueabi-g++ )
set( CMAKE_FIND_ROOT_PATH "/home/xlb/opt/arm/lib" ) #這裏要和上面編譯安裝的目錄對應
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
#最後這四個參數非常重要,如果設置不對,可能編譯完成後,仍然找不到。
保存關閉後,在終端執行
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ../ #注意這裏空格和.的個數
完成後顯示如下圖所示,FFMPEG對應部分都顯示爲yes,說明沒有問題,可以繼續下一步操作。如果FFMPEG爲NO,解決方法見以下鏈接內容:https://blog.csdn.net/m0_37967533/article/details/99623736
(2)對opencv進行cmake配置
如果pc機沒有安裝cmake,在終端執行以下命令進行安裝:
sudo apt-get install cmake cmake-gui
依舊在arm-build目錄下,輸入以下命令打開cmake界面程序:
cmake-gui
按照下圖所示進行設置,其中where is the source code選擇opencv源碼目錄, where to build the binaries爲存放生成的編譯文件的位置,CMAKE_INSTALL_PREFIX選擇自己的安裝路徑。
點擊configure,在彈出框中選擇最後一項,然後點擊next,如下圖所示:
然後進行交叉工具鏈信息配置,在“operating system”填入Linux或arm-Linux,C Compolers選擇交叉編譯器arm-linux-gnueabi-gcc,C++ Compolers選擇交叉編譯器arm-linux-gnueabi-g++,Target Root選擇交叉編譯器所在路徑,然後點擊Finish。
根據需要(你用到的庫)勾選配置文件,可參考如下選取方式:
去掉 WITH_CUDA
去掉 WITH_GTK
去掉 WITH_1394
去掉 WITH_GSTREAMER
去掉 WITH_LIBV4L
去掉 WITH_TIFF
去掉 BUILD_OPENEXR
去掉 WITH_OPENEXR
去掉 BUILD_opencv_ocl
去掉 WITH_OPENCL
參考鏈接:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70194392
依次點擊Configure和Generate,生成makefile文件。此時修改在/opencv-3.1.0/opencv-con文件夾中的CMakeCache.txt:CMAKE_EXE_LINKER_FLAGS選項本來爲空,在後面加上:-lpthread -lrt。
(3)編譯opencv
在opencv-con文件夾下執行:
make
make install
等待較長一段時間後,opencv的交叉編譯就完成了。
四、可能出現的錯誤及處理方法
錯誤一:
../../3rdparty/lib/libzlib.a(gzlib.c.obj):relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not beused when making a shared object; recompile with –fPIC
解決方式:3rdparty/zlib/CMakeFiles/zlib.dir/flags.make文件的C_FLAGS中添加-fPIC,即C_FLAGS = -W -Wall 改爲 C_FLAGS = -fPIC -W –Wall。類似的錯誤可能出現多次,需要將3rdparty文件夾下的每一個第三方庫文件夾內的flags.make都做修改。
錯誤二:
./../lib/libopencv_ocl.so: undefined reference to `dlopen'
../../lib/libopencv_ocl.so: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status
make[2]: *** [bin/opencv_perf_ocl] Error 1
make[1]: *** [modules/ocl/CMakeFiles/opencv_perf_ocl.dir/all]Error 2
make: *** [all] Error 2
解決方式:出現這個錯誤的原因是沒有找到dl庫,需要修改build裏面的CMakeCache.txt,在CMAKE_EXE_LINKER_FLAGS= -lpthread -lrt -ldl即可。
錯誤三:
配置完ffmpeg,make過程中出現如下錯誤
解決方式:
應該是版本過老的問題,最新版本接口有所調整,去http://ffmpeg.org/download.html下載最新版本的ffmpeg即可解決該問題。
錯誤四:
ffmpeg 安裝時報ERROR: libx264 not found 異常。
解決方式:前文已經提及,在配置時加上最後兩句,該部分告訴了編譯器依賴庫的安裝位置。
../configure --prefix=/home/hrx/build_opencv/opencv_depend/ --enable-gpl --enable-shared --cross-prefix=arm-poky-linux-gnueabi- --cc="arm-poky-linux-gnueabi-gcc -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7" --enable-cross-compile --arch=arm --target-os=linux --enable-nonfree --enable-pthreads --enable-ffplay --extra-cflags=-I/opt/arm/include/ --extra-ldflags=-L/opt/arm/lib/
如果還是不行,考慮路徑錯誤或者檢查命令的空格、分隔符等是否有錯誤。
錯誤四:
編譯opencv時報下圖錯誤
解決方式:
這個在前文中已經說過,在第三方庫的flag.make文件中加入-fPIC。如果還不行,參考https://www.bbsmax.com/A/x9J2DWmed6/,將ffmpeg靜態庫更改爲使用動態庫,即在終端進入opencv源碼目錄,執行:
sed -i -e 's/libavformat\.a/libavformat.so/g' \
-e 's/libavutil\.a/libavutil.so/g' \
-e 's/libswscale\.a/libswscale.so/g' \
-e 's/libavresample\.a/libavresample.so/g' \
-e 's/libavcodec\.a/libavcodec.so/g' \
cmake/OpenCVFindLibsVideo.cmake
如果有其他問題歡迎站內提問