基于CMake导入第三方库,以OpenCV为例

2023-05-16

基于CMake导入第三方库,以OpenCV为例

目录

  • 基于CMake导入第三方库,以OpenCV为例
    • 前言
    • 直接导入
    • find package
    • 基于nuget进行包管理
    • 运行的问题

前言

除了自己写一个静态库或动态库,平时在开发过程,使用第三方库是常见的选择,这样可以避免重复“造轮子”,大大加快开发进度。CMake为使用第三方库提供多种管理方式,这里介绍3种,分别为直接导入,find package导入和基于nuget进行包管理。这章将以最常见的OpenCV库为例来说明3种管理方式,示例可在https://github.com/LeiChenIntel/wheels/tree/main/cmake_guide/sample5获取。

直接导入

1,设置环境变量“OPENCV_DIR”。
在这里插入图片描述

2,在CMake中通过$ENV{OPENCV_DIR}获取环境变量,进而设置头文件包含路径和链接库路径,并链接对应的库。这里需要检查包含路径/build/include/build/x64/vc15/lib,如果和实际不符,CMake无法工作。

message("Link OpenCV build library manually")
add_definitions(-D LINK_OPENCV_LIB_MANUAL)
set(OPENCV_INC_DIR $ENV{OPENCV_DIR}/build/include)
set(OPENCV_LIB_DIR $ENV{OPENCV_DIR}/build/x64/vc15/lib)
target_include_directories(sample5 PUBLIC ${OPENCV_INC_DIR})
target_link_directories(sample5 PUBLIC ${OPENCV_LIB_DIR})
# project can change lib automatically with debug and release mode
target_link_libraries(sample5 debug opencv_world452d)
target_link_libraries(sample5 optimized opencv_world452)

3,如果要测试直接导入方式,在CMake构建工程时需使用:

cmake -DADD_OPENCV_LIB_MANUAL=ON -DADD_OPENCV_LIB_AUTO=OFF -DADD_OPENCV_LIB_NUGET=OFF ..

find package

如果只链接一个库,直接导入的方式相对简单,如果要多个库文件,一个一个写会显得繁琐。另一个问题,如果像直接导入中将头文件和库包含路径写死,一旦库结构发生调整,CMake将无法正确工作。因此,OpenCV提供了OpenCVConfig.cmake的方式来导入库,可以将所有库全部导入工程。
1,设置环境变量“OpenCV_DIR”(必须用这个变量名),确保路径下有OpenCVConfig.cmake文件。
在这里插入图片描述
2,在CMake中用 find_package 导入库。在OpenCVConfig.cmake中有很多关于库的说明,比如新定义了很多宏,可以在CMake中直接使用。

message("Link OpenCV build library via OpenCVConfig.cmake")
add_definitions(-D LINK_OPENCV_LIB_AUTO)
find_package(OpenCV REQUIRED)
include_directories(sample5 ${OpenCV_INCLUDE_DIRS})
target_link_libraries(sample5 ${OpenCV_LIBS})

在这里插入图片描述
3,如果要测试 find_package 导入方式,在CMake构建工程时需使用:

cmake -DADD_OPENCV_LIB_MANUAL=OFF -DADD_OPENCV_LIB_AUTO=ON -DADD_OPENCV_LIB_NUGET=OFF ..

基于nuget进行包管理

nuget是基于Visual Studio的包管理工具,降低第三方库的管理成本。在VS中可以在Tools->NuGet Package Manager中启动管理界面,在界面中可以搜索需要的库(boost_filesystem-vc140),指定加载的项目(sample5),选择库版本(Latest stable 1.76.0)。

在这里插入图片描述
上面是基于VS界面的设置方式,如果在CMake构建工程时就将这些设置好无疑会让事情更简单。

1,要在packages.config.in中记录库信息,这些信息要与nuget服务器 https://www.nuget.org 对应,在搜索栏找到需要的库,找到库名:“opencv.win.native”和库版本:“320.1.1-vs141”,记录在packages.config.in中。

  <package id="opencv.win.native" version="320.1.1-vs141" targetFramework="win" />

package config的更多信息可以看官方文档:https://docs.microsoft.com/zh-cn/nuget/reference/packages-config

2, 在CMake中包含库头文件,链接库文件。在VS里build时(在用CMake构建工程时不会下载库,下载是在build过程中发生的),第三方库会下载到./pakcages文件夹里,之后的目录结构取决于库本身,所以要检查目录结构并将其正确填写进CMake。

message("Link OpenCV via Nuget")
# Need file packages.config.in with packages information.
configure_file(packages.config.in ${CMAKE_CURRENT_BINARY_DIR}/packages.config NEWLINE_STYLE CRLF)
# After set OPENCV_PKG, sample5 should have been linked by "target_link_libraries(sample5 ${OPENCV_PKG})". However,
# the .targets file is only prepared for v141 (VS2017). OpenCV have to be linked manually when v142 (VS2019) used.
# set(OPENCV_PKG ${CMAKE_BINARY_DIR}/packages/opencv.win.native.320.1.1-vs141/build/native/opencv.win.native.targets)
target_include_directories(sample5 PUBLIC ${CMAKE_BINARY_DIR}/packages/opencv.win.native.320.1.1-vs141/build/native/include)
# target_link_libraries(sample5 ${OPENCV_PKG})
set(OPENCV_LIB_DIR
	${CMAKE_BINARY_DIR}/packages/opencv.win.native.320.1.1-vs141/build/native/lib/x64/v141/Debug
	${CMAKE_BINARY_DIR}/packages/opencv.win.native.320.1.1-vs141/build/native/lib/x64/v141/Release)
target_link_directories(sample5 PUBLIC ${OPENCV_LIB_DIR})
# target cannot judge debug/release lib automatically here.
if(OPENCV_LIB_NUGET_DEBUG)
	target_link_libraries(sample5
		opencv_videoio320d
		opencv_imgproc320d
		opencv_imgcodecs320d
		opencv_highgui320d
		opencv_core320d)
else()
	target_link_libraries(sample5
		opencv_videoio320
		opencv_imgproc320
		opencv_imgcodecs320
		opencv_highgui320
		opencv_core320)
endif()

3,如果要测试 nuget 库管理方式,在CMake构建工程时需使用:

cmake -DADD_OPENCV_LIB_MANUAL=OFF -DADD_OPENCV_LIB_AUTO=OFF -DADD_OPENCV_LIB_NUGET=ON ..

使用nuget的优势:
可以对第三方库进行版本管理,确保在不同机器上build都使用完全相同的第三方库,便于协同开发。在企业开发中,这是一个比较好的选项。
使用nuget的劣势:
因为每次build都要下载一份第三方库,开发机是需要接入网络的,build的工程会比较大。nuget的服务器上必须有需要的库,而且版本要符合需求,比如,理论上VS2019要vc142的库,VS2017要vc141,VS2015要vc140,不符合需求在加载过程中会遇到一些障碍。目前 nuget 应该只支持Visual Studio系列开发环境,如果用非MS开发环境如CLion库无法正常加载。

运行的问题

sample5作为一个简单的示例,具有读取图片并输出的功能,在找到正确的动态库(opencv_*320.dll)后应该能运行,

sample5.exe D:\opencv-logo.png

可能会出现无法找到zlib1.dll的问题,需要在网络上下载或在系统中找到并包含这个动态库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于CMake导入第三方库,以OpenCV为例 的相关文章

随机推荐

  • 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别

    POSIX 同步IO 异步IO 阻塞IO 非阻塞IO xff0c 这几个词常见于各种各样的与网络相关的文章之中 xff0c 往往不同上下文中它们的意思是不一样的 xff0c 以致于我在很长一段时间对此感到困惑 xff0c 所以想写一篇文章整
  • Google Dapper-大规模分布式系统的基础跟踪设施

    说明 xff1a 本文是阅读Google论文 Dapper a Large Scale Distributed Systems Tracing Infrastructure 之后的一个简要总结 xff0c 完整译文可参考此处 另论文 Unc
  • 分布式会话跟踪系统架构设计与实践

    本文整理自美团点评技术沙龙第08期 xff1a 大规模集群的服务治理设计与实践 美团点评技术沙龙由美团点评技术团队主办 xff0c 每月一期 每期沙龙邀请美团点评及其它互联网公司的技术专家分享来自一线的实践经验 xff0c 覆盖各主要技术领
  • 学术工具-Citavi 简介

    因为之前也有过看了文献的经历 xff0c 每次都要打印出来 xff0c 然后再纸上写笔记等等 xff0c 可能回头了还找不到关键记号等问题 xff0c 决心有工具就好好利用起来 现在也刚好有机会 xff0c 在知乎上看到了一位现大一大神做的
  • Qt5.7.0 mingw+qwtplot3D 编译

    一 基本编译问题 在安装的过程中却遇到了很多的问题 咨询了Google中大量的帖子 xff0c 发现按照他们说的方法根本没法解决我的实际问题 研究了整整宝几天 xff0c 总算是编译通过 xff0c 解决了所有的问题 下面将通过重现我的安装
  • 一篇实用的Latex的入门教程

    转载 LaTeX新人教程 xff0c 一小时从完全陌生到基本入门 作者 董楠 LaTeX新人教程 xff0c 一小时从完全陌生到基本入门 by Nan 对于真心渴望迅速上手LaTeX的人 xff0c 可以只看正文 曾经在缝缝补补中变得长长的
  • Qt5.8.0使用QChart的问题

    Qt Charts 的横空出世标识着 QWT QCustomPlot 时代的终结 xff0c 是时候向他们做一个简单的告别了 Qt Charts 强大并极具吸引力 xff0c 从现在开始 xff0c 让我们顺势拥抱灿烂的明天 引自 xff1
  • 成功实现NAS家庭服务器(流媒体播放、文件共享及下载机)

    一 家庭服务器实现的主要功能 1 流媒体播放服务 xff1a 利用DLNA实现电视 手机 电脑播放其上面的媒体文件 2 文件共享 xff1a 利用samba实现手机 电脑等终端与服务器的文件共享 3 自动下载 xff1a 利用aria2c实
  • 架构漫谈(八):从架构的角度看如何写好代码 + 我的思考

    我的总结 xff1a 当先前对于利益相关者的关系理清了 xff0c 系统基本架构和测试方法等也有了 xff0c 进入实际Coding阶段 在Coding前 xff0c 需要我们考虑好业务功能的分配 xff0c 关注于功能会频繁变更的部分 x
  • 插头类型:MX 1.25 PH间距2.0、XH间距2.5/2.54、VH间距3.96区别?

    PH xff0c XH xff0c ZH等这些都是JST xff08 Japan Standard Time 日本压着端子制造株式会社 xff09 的料号 xff0c 因为JST用的最多 xff0c 且很多工厂都在模仿制作 xff0c 故也
  • 树莓派NAS搭建——基于OMV

    之前树莓派的debian版系统里装了个以samba服务为基础的NAS xff0c 但在实际使用中发现写入速度只有2M s xff0c 特别慢 xff0c 用的是Class 10的高速TF卡也于事无补 实在无法直视 xff0c 于是一直在搜寻
  • 最短路径算法——Dijkstra介绍

    个人心得体会 xff1a 理解这种或这类算法 xff0c 可以先从小规模的问题入手 xff0c 并逐渐推广到问题变复杂的情况 xff0c 这样理解起来也可以更方便和透彻 和数学归纳法很相似 图简介 以使用地图APP为例 xff0c 假设你想
  • net framework4.0未能成功安装、另一个安装操作正在进行、请继续这个操作之前完成那个操作。

    转自百度 安装net framework 4 0出错的解决方法 步骤 xff1a 开始 运行 xff08 输入CMD xff09 确定或者回车 xff0c 打开管理员命令窗口 xff1b 在管理员命令窗口输入 xff1a net stop
  • java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver

    第一次写jsp xff0c 用jdbc连接数据库进行查询的时候 xff0c Class forName 34 com microsoft jdbc sqlserver SQLServerDriver 34 newInstance conn
  • numpy Array [: ,] 的取值方法

    numpy Array 的取值方法 NumPy数组是一个多维数组对象 xff0c 称为ndarray 创建一个numpy数组 如下所示 span class token keyword import span numpy span clas
  • 如何安装windows和linux双系统

    最近装了两天系统积攒了一下经验 原本一直使用win7 xff0c 现需要使用linux操作系统作为开发环境 xff0c 虚拟机的能力总是有限 xff0c 所以打算装双系统 xff0c 装系统以前一直对我来说一直很神秘 xff0c 为什么系统
  • sed -i命令详解

    sed i命令详解 root 64 www sed nefr 动作 选项与参数 xff1a n xff1a 使用安静 silent 模式 在一般 sed 的用法中 xff0c 所有来自 STDIN 的数据一般都会被列出到终端上 但如果加上
  • 模拟信号和数字信号的区别

    作者 xff1a 杨眀 链接 xff1a https www zhihu com question 38377832 answer 118464689 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业
  • 于渊《orange's 一个操作系统实现》的字符串输出函数disp_str有bug会导致异常

    于渊先生的 orange s 一个操作系统实现 的字符串输出函数disp str有bug会导致异常 发现在同一个函数中两次使用disp str就会导致异常 xff0c 这个问题困扰了我很久 xff0c 一般来说都是堆栈的没有恢复好的问题 x
  • 基于CMake导入第三方库,以OpenCV为例

    基于CMake导入第三方库 xff0c 以OpenCV为例 目录 基于CMake导入第三方库 xff0c 以OpenCV为例前言直接导入find package基于nuget进行包管理运行的问题 前言 除了自己写一个静态库或动态库 xff0