多版本opencv管理; find_package()的原理解析
背景
使用cmake编译C++工程,工程依赖指定版本的opencv和pcl。因此需要在CMakeLists.txt中切换不同版本的依赖库。
电脑配置
ubuntu16.04, ros-kinetic,opencv2和opencv3,pcl1.7(ros携带)和pcl1.9(源码编译)。
1. 使用find_package(Opencv REQUIRED) 寻找指定的库
find_package() 指令优先找到opencv3。如果要用opencv2,有两个方法可以实现:
a. 墙裂推荐此法
设置库的路径同时显式指定版本(假定指定版本的opencv安装在 /usr/local 目录中)。
set(OpenCV_DIR /usr/local/opencv2/share/OpenCV)
FIND_PACKAGE( OpenCV 2.4.9 REQUIRED )
关于pcl。如果需要使用ros携带的pcl库,在CMakeLists.txt中添加如下命令行,
set(PCL_DIR "/usr/lib/x86_64-linux-gnu/cmake/pcl") #该路径中存放*.cmake文件
find_package(PCL 1.7 REQUIRED)
b. 编译程序之前,在terminal中输入以下指令(假定多个版本的opencv都安装在 /usr/local 目录中)。
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opencv2/lib/pkgconfig
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/opencv2/lib
输入以下指令让动态链接库为系统所共享,可理解为使系统读取我们设置的环境变量。
sudo ldconfig
Note : 采用第二种方法有个重要前提,就是多个版本的opencv都必须安装在 /usr/local 中,这时候编译器直接在该目录下搜索目标链接。但是,由于我安装了ros-kinetic,其自带ros-kinetic-opencv3.3,该库的安装路径在编译器搜索链接的过程中具有较高的优先级,因此,编译器优先链接到该库。如下图所示,通过echo环境变量,可以看到多个版本的opencv具有不同的优先级。
如何修改这个优先级呢?
可以通过修改环境变量PKG_CONFIG_PATH和LD_LIBRARY_PATH来改变这个优先级。
2. find_package(Opencv REQUIRED) 如何寻找库
理解find_package()的原理,必须先了解一个工具 -- pkg-config .
该部分内容参考了https://blog.csdn.net/bryce_xiao/article/details/70787810
pkg-config可用于列举出某个库的相关信息,比如此库的路径、相关头文件路径等,这在程序编译时将非常有用。例如,现在要编译一个依赖librtmp.so库的程序。去哪找librtmp.so相关的头文件呢?librtmp.so库又在哪呢?这是一个大问题,但有了pkg-config后这些都不是问题。先使用以下命令看看:
xjh@debian:~$ pkg-config --cflags librtmp
-I/usr/local/include xjh@debian:~$ pkg-config --libs librtmp
-L/usr/local/lib -lrtmp -lz -lssl -lcrypto
看到没,pkg-config能找出头文件的路径,也能找出库存放在哪,而且还能知道依赖的其它库。
有了pkg-config后,当我编译程序要使用librtmp.so库时,就可以这么写:
xjh@debian:~$ gcc sample.c -o sample `pkg-config --cflags --libs librtmp`
哈哈哈哈,有了pkg-config,妈妈再也不用担心我程序编译时找不到库了。
那么,问题也来了,pkg-config又是如何知道库存放路径及头文件路径等信息的呢?
答案就在.pc文件中。库文件编译完成后,会在{installed_home/lib/}下生成产生一个名为pkgconfig的目录,内含该链接库的.pc文件,此文件记录了改库的相关信息。为了能被查找读取到,需要将该.pc文件安装到 /usr/lib/pkgconfig/ 目录中,或在PKG_CONFIG_PATH环境变量中加入该.pc文件的安装路径。这样做的目的是为了使依赖此库的其它程序能够借助pkg-config自动链接该库,避免编译期错误。
pkg-config常用参数:
–-list-all 列出所有已安装的共享库
-–cflags 列出指定共享库的预处理和编译flag。
-–libs 列出指定共享库的链接flag。
环境变量 PKG_CONFIG_PATH 用于指定pkg-config查找.pc文件的路径。此外,pkg-config还会查找/usr/lib/pkgconfig/下的.pc文件。也即是说,find_package()是通过pkg-config来查找指定的库。
多版本opencv管理; find_package()的原理解析的更多相关文章
- Ubuntu下多个版本OpenCV管理(Multiple Opencv version)
背景: 最近,在Nvidia的GPU嵌入式开发板Jetson TX1(简称TX1)上移植深度学习目标检测算法YOLO.在TX1上安装了官方提供的opencv版本——OpenCV4Tegra(OpenC ...
- 使用 vscode 插件可视化制作和管理脚手架及原理解析
提到脚手架,大家想到的可能就是各种 xxx-cli,本文介绍的是另一种方式:以 vscode 插件的形式实现,提供 web 可视化操作,如下图: 下面介绍如何安装使用,以及实现原理. 安装使用 vsc ...
- 【spring源码学习】spring的事务管理的源码解析
[一]spring事务管理(1)spring的事务管理,是基于aop动态代理实现的.对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transact ...
- 基于OpenCV进行图像拼接原理解析和编码实现(提纲 代码和具体内容在课件中)
一.背景 1.1概念定义 我们这里想要实现的图像拼接,既不是如题图1和2这样的"图片艺术拼接",也不是如图3这样的"显示拼接",而是实现类似"BaiD ...
- C#的内存管理原理解析+标准Dispose模式的实现
本文内容是本人参考多本经典C#书籍和一些前辈的博文做的总结 尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能 ...
- [置顶]
滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理
上周末,滴滴与360都开源了各自的插件化框架,VirtualAPK与RePlugin,作为一个插件化方面的狂热研究者,在周末就迫不及待的下载了Virtualapk框架来进行研究,本篇博客带来的是Vir ...
- [原][Docker]特性与原理解析
Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...
- 开源磁力搜索爬虫dhtspider原理解析
开源地址:https://github.com/callmelanmao/dhtspider. 开源的dht爬虫已经有很多了,有php版本的,python版本的和nodejs版本.经过一些测试,发现还 ...
- Tengine HTTPS原理解析、实践与调试【转】
本文邀请阿里云CDN HTTPS技术专家金九,分享Tengine的一些HTTPS实践经验.内容主要有四个方面:HTTPS趋势.HTTPS基础.HTTPS实践.HTTPS调试. 一.HTTPS趋势 这一 ...
随机推荐
- Centos 中 service iptables stop 失败
Centos7中的防火墙调整为firewalld,试一下systemctl stop firewalld关闭防火墙.
- 锯齿状优惠券css绘制
对于图上优惠券左右两侧的半圆锯齿效果,两种处理方式,一种直接使用切图进行处理,一种是纯css进行效果绘制.切图的就不再赘述,主要说纯css效果绘制 绘制的结果如下图: 难点在于两侧的半圆孔是透明色,不 ...
- Mysql按周,按月,按日,按小时分组统计数据
按周 select DATE_FORMAT(create_time,'%Y%u') weeks,count(caseid) count from tc_case group by weeks; ...
- mysql 取年、月、日、时间
select id, phone,time,year(time),month(time), DAY(time),TIME(time) from user where phone='xxxxxx' #分 ...
- 微信小程序城市定位(百度地图API)
概述 微信小程序提供一些API(地址)用于获取当前用户的地理位置等信息,但无论是wx.getLocation,还是wx.chooseLocation均没有单独的字段表示国家与城市信息,仅有经纬度信息. ...
- C++获取数组的长度
C++获取数组的长度 #include<iostream> using namespace std; template<class T> int length(T& a ...
- linux如何让一个程序崩溃后自动重启
思路: 写一个脚本 监控程序的运行状态 没有运行启动运行 已运行不做操作. 如果在控制台启动脚本 注意必须 nohup sh xxx.sh & while true do ps -ef ...
- coursera-斯坦福-机器学习-吴恩达-笔记week2
1 多元线性回归 1.1 假设函数 多元线性回归是指有多个特征特征变量的情况.此时我们修改假设函数hθ(x)=θ0+θ1∗x为hθ(x)=θ0+θ1x1+θ2x2+⋯+θnxn.设x0=1,x为特征向 ...
- jdk安装环境变量配置
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- css实现半圆和圆
1.半圆 半圆分为:上半圆.下半圆.左半圆.右半圆,我们只要学会制作某一个方向的半圆,其他方向的半圆都可以轻松实现,其原理都一样. 假如我们要制作上半圆,实现原理:把高度height设置为宽度widt ...