记录用,目的是编译一个尽量没有外部依赖的.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和他的依赖被弄成静态库后,动态链接中就没再有依赖需要了。
