Ubuntu下编译安装opencv,以及软链接、so版本号的处理
写在最前:Ubuntu下编译安装opencv还是比较简单的,最近要发布依赖opencv的程序,突然发现编译安装的opencv有两层软链接:
libopencv_world.so.4.4 -> libopencv_world.so.4.4.0
libopencv_world.so -> libopencv_world.so.4.4
结果依赖opencv的程序显示依赖的库为libopencv_world.so.4.4,但实际的so应该是libopencv_world.so.4.4.0
本文记录一下解决的两种方法:
- 将两层软链接改为一层软链接
- 去掉so后边的版本号信息
1. 编译安装opencv(正常流程)
1.1 安装依赖环境
- 安装cmake
sudo apt-get install cmake
- 安装其他依赖项
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev
sudo apt-get install libgtk2.0-dev
sudo apt-get install pkg-config
1.2 下载opencv源码
有两个下载地址:
- opencv官方网址:https://opencv.org/releases/
- github:https://github.com/opencv/opencv/releases
选择下载对应版本的源码即可
1.3 编译安装
- 解压下载的源码包,并进入该文件夹,4.4.0版本解压后如下:
- 新建脚本文件generate_opencv_world.sh,用于编译(也可以在控制台直接输入命令,建议养成写脚本的习惯)
rm -rf build_world
mkdir build_world && cd build_world
cmake -D CMAKE_BUILD_TYPE=Release -D BUILD_opencv_world=ON -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j$(nproc)
make install
这里cmake参数写的很少,更多设置这里不做详述
BUILD_opencv_world=ON代表只生成一个so,如果想生成各模块单独的so,设为OFF即可。
- 运行脚本
sudo sh ./generate_opencv_world.sh
- 结果
完成后会生成三个文件:
- libopencv_world.so.4.4.0
- libopencv_world.so.4.4
- libopencv_world.so
其中只有 libopencv_world.so.4.4.0 是生成的so文件,其他两个是软链接
但在实际使用的过程中,生成的可执行文件依赖的是 libopencv_world.so.4.4,发布程序比较麻烦
2. 两层软链接变为一层软链接
需要改的地方很少,只需找到【opencv-4.4.0】-【cmake】-【OpenCVModule.cmake】文件,找到其中如下代码:
# For dynamic link numbering conventions
if(NOT ANDROID)
# Android SDK build scripts can include only .so files into final .apk
# As result we should not set version properties for Android
set_target_properties(${the_module} PROPERTIES
VERSION ${OPENCV_LIBVERSION}
SOVERSION ${OPENCV_SOVERSION}
)
endif()
将其中的SOVERSION注释掉即可:
if(NOT ANDROID)
# Android SDK build scripts can include only .so files into final .apk
# As result we should not set version properties for Android
set_target_properties(${the_module} PROPERTIES
VERSION ${OPENCV_LIBVERSION}
# SOVERSION ${OPENCV_SOVERSION}
)
endif()
下边对其中几个关键字做出解释:
- set_target_properties
- 设置目标属性
- VERSION
- 目标版本号
- SOVERSION
- 目标版本号
对于VERSION和SOVERSION,官方的解释如下:
For shared libraries VERSION and SOVERSION can be used to specify the build version and API version respectively. When building or installing appropriate symlinks are created if the platform supports symlinks and the linker supports so-names. If only one of both is specified the missing is assumed to have the same version number. For executables VERSION can be used to specify the build version. When building or installing appropriate symlinks are created if the platform supports symlinks.
即VERSION和SOVERSION可以指定生成的版本号及软链接的版本号
3. 去掉so后边的版本号
如果不需要在so中添加版本号信息,则可以直接去掉,直接输出 libopencv_world.so
去掉版本号的方法很简单,直接把这个属性的设置注释掉就好:
# # For dynamic link numbering conventions
# if(NOT ANDROID)
# # Android SDK build scripts can include only .so files into final .apk
# # As result we should not set version properties for Android
# set_target_properties(${the_module} PROPERTIES
# VERSION ${OPENCV_LIBVERSION}
# SOVERSION ${OPENCV_SOVERSION}
# )
# endif()