【Linux】opencv4.9.0静态库编译,开启opencl和EIGEN矩阵运算

记录用,目的是编译一个尽量没有外部依赖的.a文件,让其他程序引用该opencv库的时候不用连携额外的依赖

先克隆和准备构建目录

c 复制代码
git clone -b 4.9.0 --depth=1 https://github.com/opencv/opencv.git 
cd opencv
mkdir build && cd build

准备一些依赖(可能不够全,我过程中打了太多install,这起码是必备的一些)

c 复制代码
# 1. 更新系统包索引
sudo apt update && sudo apt upgrade -y

# 2. 安装基础编译工具
sudo apt install -y build-essential cmake git pkg-config wget unzip

# 3. 安装OpenCV依赖的图像处理库
sudo apt install -y libjpeg-dev libpng-dev libtiff-dev libjasper-dev
sudo apt install -y libxvidcore-dev libx264-dev libgtk-3-dev libatlas-base-dev
sudo apt install -y gfortran libtbb-dev

# 4. 安装OpenCL依赖(OpenCL运行时+开发库)
sudo apt install -y opencl-headers ocl-icd-opencl-dev

# 5. 安装Eigen3(线性代数库,OpenCV依赖其做矩阵运算)
sudo apt install -y libeigen3-dev

我们开始执行cmake,cmake如下

c 复制代码
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_opencv_world=ON -D WITH_OPENCL=ON -D WITH_OPENCL_FP16=ON -D OPENCV_ENABLE_NONFREE=OFF -D BUILD_SHARED_LIBS=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D BUILD_DOCS=OFF -D BUILD_opencv_videoio=OFF -D BUILD_opencv_video=OFF -D BUILD_opencv_highgui=OFF -D BUILD_opencv_calib3d=OFF -D OPENCV_LINKER_LIBS="libjpeg.a;libpng.a;libtiff.a;libwebp.a" -D OPENCV_STATIC=ON -D BUILD_RPATH=OFF -D CMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic" -D OpenCL_LIBRARY=/usr/lib/x86_64-linux-gnu/libOpenCL.so -D OpenCL_INCLUDE_DIR=/usr/include/CL -D WITH_OPENJPEG=ON -D BUILD_OPENJPEG=ON -D OPENJPEG_BUILD_SHARED=OFF -D OPENJPEG_BUILD_STATIC=ON -D CMAKE_LINK_WHAT_YOU_USE=ON -D CMAKE_FIND_LIBRARY_SUFFIXES=.a -D BUILD_opencv_version=OFF -DWITH_LAPACK=OFF -DWITH_BLAS=OFF -DWITH_EIGEN=ON ..

按个人需求增减,简单的解释如下

CMAKE_BUILD_TYPE=Release

生成优化版(-O3 -DNDEBUG),体积最小、速度最快,后续不可再 gdb 单步。

CMAKE_INSTALL_PREFIX=/usr/local

安装目的地;make install 时把头文件与 .a 放到 /usr/local/{include,lib}。
BUILD_opencv_world=ON
把所有选中模块打成单一 libopencv_world.a
WITH_OPENCL=ON / WITH_OPENCL_FP16=ON
打开 OpenCL 运行时支持
OPENCV_ENABLE_NONFREE=OFF
显式禁用 SIFT/SURF 等专利算法。
BUILD_SHARED_LIBS=OFF
强制只产静态库(
.a),不会产生任何 *.so。

BUILD_TESTS=OFF / BUILD_PERF_TESTS=OFF BUILD_EXAMPLES=OFF / BUILD_DOCS=OFF

跳过测试、性能基准、示例和文档,节省 70% 以上编译时间。

BUILD_opencv_videoio=OFF /BUILD_opencv_video=OFF BUILD_opencv_highgui=OFF BUILD_opencv_calib3d=OFF

只做图像处理,因此把摄像头/视频捕获、高级 GUI、标定功能全部剔除,减小体积。

OPENCV_LINKER_LIBS="libjpeg.a;libpng.a;libtiff.a;libwebp.a"

告诉 CMake"链接阶段优先找这些第三方静态库",配合后面 CMAKE_FIND_LIBRARY_SUFFIXES=.a 可确保把 jpeg/png/tiff/webp 的静态版本嵌进 world 里,运行时不再拖 *.so。

OPENCV_STATIC=ON

BUILD_RPATH=OFF

CMAKE_EXE_LINKER_FLAGS="-static-libstdc++ -static-libgcc -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic"

把 libstdc++ 和 libgcc 静态链接

OpenCL_LIBRARY=/usr/lib/x86_64-linux-gnu/libOpenCL.so

OpenCL_INCLUDE_DIR=/usr/include/CL

WITH_OPENJPEG=ON / BUILD_OPENJPEG=ON / OPENJPEG_BUILD_SHARED=OFF OPENJPEG_BUILD_STATIC=ON

CMAKE_LINK_WHAT_YOU_USE=ON

CMAKE_FIND_LIBRARY_SUFFIXES=.a

BUILD_opencv_version=OFF

跳过生成 opencv_version 可执行小工具,再省一次编译。

WITH_LAPACK=OFF WITH_BLAS=OFF WITH_EIGEN=ON

关闭 LAPACK/BLAS(免得引入符号问题:undefined symbol: dgeqrf_,

改用纯头文件的 Eigen(已通过 apt 装好)

编译和安装

c 复制代码
make-j8
sudo make install
sudo ldconfig

假设你git下来的opencv在/home/main/下载/go/opencv

那么最终.a文件的位置如下

/home/main/下载/go/opencv/build/lib/libopencv_world.a

他依赖的静态库.a位置如下

.../opencv/build/3rdparty/lib/liblibopenjp2.a

.../opencv/build/3rdparty/lib/libade.a

.../opencv/build/3rdparty/lib/liblibpng.a

.../opencv/build/3rdparty/lib/liblibtiff.a

.../opencv/build/3rdparty/lib/liblibjpeg-turbo.a

.../opencv/build/3rdparty/lib/libIlmImf.a

.../opencv/build/3rdparty/lib/libittnotify.a

.../opencv/build/3rdparty/lib/libippiw.a

.../opencv/build/3rdparty/lib/libzlib.a

.../opencv/build/3rdparty/lib/liblibwebp.a

.../opencv/build/3rdparty/lib/liblibprotobuf.a

.../opencv/build/3rdparty/ippicv/ippicv_lnx/icv/lib/intel64/libippicv.a

那么接下来说说使用:

比如我要在一个自己写的so中引用这个opencv库,那么对这个库的链接写法是(makefile形式)

c 复制代码
CXXFLAGS = -std=c++17 -Wall -fPIC -fopenmp -shared -I/usr/local/include/opencv4 `pkg-config --cflags eigen3`
# 链接选项
LDFLAGS = -fopenmp `pkg-config --libs eigen3` -Wl,-Bstatic ./libopencv_world.a \
          ./libade.a \
          ./libIlmImf.a \
          ./libippiw.a \
          ./libittnotify.a \
          ./liblibjpeg-turbo.a \
          ./liblibopenjp2.a \
          ./liblibpng.a \
          ./liblibprotobuf.a \
          ./liblibtiff.a \
          ./liblibwebp.a \
          ./libzlib.a \
		  ./libippicv.a \
		  -Wl,-Bdynamic -Wl,-rpath=./
# 头文件搜索路径(当前目录 + 系统 Eigen 路径,双重保障)
INCLUDES = -I. -I/usr/include/eigen3

你可能注意到了这些opencv的静态库本身和他的静态依赖库都是当前目录的./开头

那是因为我把这些.a文件都拷出来放一起了

成果:

libmediaQualDll.so是我自己写的库,引用了上文编译出来的opencv静态库。

可以看到,opencv和他的依赖被弄成静态库后,动态链接中就没再有依赖需要了。

相关推荐
松涛和鸣3 分钟前
48、MQTT 3.1.1
linux·前端·网络·数据库·tcp/ip·html
大小鱼鱼鱼与鱼.6 分钟前
linux磁盘扩展
linux·运维·服务器
行稳方能走远6 分钟前
Android C++ 学习笔记2
c++
星火开发设计6 分钟前
链表详解及C++实现
数据结构·c++·学习·链表·指针·知识
修炼地8 分钟前
代码随想录算法训练营第五十三天 | 卡码网97. 小明逛公园(Floyd 算法)、卡码网127. 骑士的攻击(A * 算法)、最短路算法总结、图论总结
c++·算法·图论
QQ_4376643148 分钟前
Qt-框架
c++·qt
※※冰馨※※18 分钟前
【QT】初始化显示时正常,操作刷新后布局显示问题。
开发语言·c++·windows·qt
linux修理工19 分钟前
sed替换文字和vim里替换文字
linux
溟洵21 分钟前
【C++ Qt 】中的多线程QThread已经线程安全相关的锁QMutex、QMutexLocker
c++·后端·qt
Lhan.zzZ23 分钟前
嵌入式Qt接收串口数据错乱问题分析:缓冲区残留数据的陷阱
开发语言·c++·qt