最近尝试在ubuntu20.04上搭建树莓派4b的交叉编译环境,参考了很多博客,发现有很多的坑,主要记录一下遇到的问题
1. 首先去git上下载交叉编译工具/自己编译
(1)查看自己的树莓派gcc版本
gcc -v
是gcc8.3.0的,需要对应版本的交叉编译工具,但是git上面没有找到gcc8.3.0的交叉编译工具,就需要自己编了,git官方的地址如下:
(2)自行编译交叉编译工具
主要参考下面这个教程:(比较费时间)
期间碰到一个error,参考了下面这个教程解决
https://blog.youkuaiyun.com/davidhopper/article/details/79681695
https://blog.youkuaiyun.com/davidhopper/article/details/79681695
如果能直接在git上找到能用的交叉编译工具,也ok
2. 然后下载opencv4.5
GitHub - opencv/opencv: Open Source Computer Vision Library
我这用的opencv4.5.5
解压出来
tar -xvzf opencv-4.5.5.tar.gz
并建立两个文件夹
cd opencv-4.5.5/
mkdir build
mkdir install
3 . 再设置一下cmake
(1)安装cmake-gui
sudo apt-get install cmake-gui
(2)配置
如下图,先把上面两行source 和 build选好
再点Configure,配置成下面这样
其中,版本可以上树莓派用 uname -a,处理器用cat /proc/cpuinfo 查看(随便写估计没啥影响)
主要把Compilers填了,target root填了,填交叉编译工具放置的地址
然后finish之后,再点一下configure,ok之后,点一下Generate
(3)配置CMakeCache.txt
还需要设置一下安装路径
CMAKE_INSTALL_PREFIX:PATH=/home/ztj/Projects/PRJ4_Pi/opencv-4.5.5/install
(4)尝试编译
make -j8
(5)碰到error1
交叉编译features.h:272:52: error: operator ‘&&‘ has no right operand
找到该文件下面这句
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
在#if defined前面 加上
#define _FILE_OFFSET_BITS 64
参考:https://blog.youkuaiyun.com/amxld/article/details/111565705
(6)碰到error2
common.cc报找不到thread,要加宏
#define HAVE_PTHREAD
(7)碰到error3
pthread相关的error
usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `pthread_key_create'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dladdr'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `pthread_getspecific'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dlopen'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `pthread_key_delete'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dlclose'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dlsym'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `pthread_setspecific'
在CmakeCache.txt中找到CMAKE_EXE_LINKER_FLAGS:STRING,加上-pthread -ldl -lrt
发现依然有错,还剩:
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dladdr'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dlopen'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dlclose'
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_core.so: undefined reference to `dlsym'
翻了半天各种博客,最后找到答案,可能和gcc版本有关,把CMAKE_EXE_LINKER_FLAGS:STRING改成如下
CMAKE_EXE_LINKER_FLAGS:STRING=-pthread -Wl,--no-as-needed -ldl -lrt
参考
https://stackoverflow.com/questions/20369672/undefined-reference-to-dlsym
4. 编译通过
sudo make install
会安装在/home/ztj/Projects/PRJ4_Pi/opencv-4.5.5/install路径下
5. 上机测试
把install目录下的文件拷到树莓派上,然后PC端编个简单的代码,生成可执行文件,放到树莓派上测试
#include <iostream>
#include <opencv2/highgui.hpp>
using namespace cv;
int main() {
cv::Mat test = cv::Mat(200,200,CV_8UC1);
test.setTo(100);
cv::imwrite("/home/pi/a.png",test);
std::cout << "Hello, PI!" << std::endl;
return 0;
}
cmakelist.txt:
make_minimum_required(VERSION 3.21)
project(test_code)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_BUILD_TYPE Release)
set(ARM_MODE TRUE)
IF (ARM_MODE) # pi
#opencv
message("ARM_MODE!!!!!!!")
set(OpenCV_DIR /home/ztj/Projects/PRJ4_Pi/opencv-4.5.5/install/lib/cmake/opencv4)
find_package(OpenCV 4.5.5 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
message("opencv ${OpenCV_VERSION}")
message("opencv ${OpenCV_DIR}")
#cmake compiler
set(CMAKE_CROSSCOMPILING TRUE)
SET(CMAKE_SYSTEM_NAME linux)
SET(CMAKE_SYSTEM_PROCESSOR "arm")
SET(CMAKE_C_COMPILER /opt/cross-pi-gcc8.3/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /opt/cross-pi-gcc8.3/bin/arm-linux-gnueabihf-g++)
#cmake_flage
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w -O3 -s -march=armv7 -pthread -Wl,--no-as-needed -ldl -lrt")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -O3 -s -march=armv7 -pthread -Wl,--no-as-needed -ldl -lrt")
add_executable(test_code main.cpp)
target_link_libraries(test_code ${OpenCV_LIBS})
else ()
message("PC_MODE!!!!!!!")
#opencv
set(OpenCV_DIR /home/ztj/software/opencv455/lib/cmake/opencv4)
find_package(OpenCV 4.5.5 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
message("opencv ${OpenCV_VERSION}")
message("opencv ${OpenCV_DIR}")
##cmake_flage
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w -O3 -s")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -O3 -s")
add_executable(test_code main.cpp)
target_link_libraries(test_code ${OpenCV_LIBS})
endif ()
树莓派上,设置环境变量export LD_LIBRAR_PATH=你放置的opencv libs路径,然后执行可执行文件,不报错就ok