前言

我一直不知道编译的过程以及cmake, make 这些工具是干什么的,所有抽时间研究了一下。
简单来说就是 cmake 是根据 CMakeLists.txt 用来生成 makefile文件的。而make 命令是根据 makefile 来生成可供使用的 动态连接库 或静态连接库的,以便你项目调用,make 命令在windows上与g++ gcc等命令在一个目录,不需要单独去下载,安装好 mingw 就是在其 bin 目录下,叫 mingw32-make.exe。

环境准备

opecv 项目如果你下载了vc++版本的也不需要重新下载源码了,因为解压后目录中包含源码,也是存放在 source目录下。
mingw安装好后将其中的 bin 目录设置到path环境变量中,以便后面cmake可以直接识别。

1.编译动态链接库

1.1 mingw 预配置


Where is the source code: 解压opencv项目后源码存放路径
Where to build the binaries: 存放构建的目录,可以是不存在的,因为点击configure会自动建立

设置好两个路径后可以直接点击 configure

选择MinGw makefiles,用默认本地编译器,然后点击下一步。

The CXX compiler identification is GNU 8.1.0
The C compiler identification is GNU 8.1.0
Detecting CXX compiler ABI info
Detecting CXX compiler ABI info - done
Check for working CXX compiler: C:/MinGW/bin/g++.exe - skipped
Detecting CXX compile features
Detecting CXX compile features - done
Detecting C compiler ABI info
Detecting C compiler ABI info - done
Check for working C compiler: C:/MinGW/bin/gcc.exe - skipped
Detecting C compile features
Detecting C compile features - done

开始检测环境,可以看到识别到了 g++ gcc等命令

1.2配置参数

参数很多,说几个可能用到的。

名字 作用
CMAKE_INSTALL_PREFIX 最终编译后存放的路径,此时这个目录可能是不存在的,只有最好执行make install命令才会建立
BUILD_opencv_python3 建立opencv python的第三方库,由于我这里不需要跟python相关的所以跟python相关我都取消勾选了
BUILD_opencv_world 将多个连接库合并成一个world链接库方便连接,建议勾选上
BUILD_SHARED_LIBS 是否建立dll, 如果不勾选就是建立静态库,默认勾选就是建立动态连接库

这里寻找选项有一个技巧,可以将

Grouped勾选上,方便寻找。
这里一步配置参数可以把 BUILD_opencv_world 选上,其余的几乎都不用动。

1.3生成makefile文件

点击 Generate 按钮, 等待生成。

这里可能会有一个问题Unable to open cache file for save. ....CMakeCache.txt
就是无法打开CMakeCache.txt 文件,我尝试过删除这个文件或者清除缓存,删不掉。
解决办法:1. 就是更换build目录,需要然后需要从新 configure, 修改配置和 generate,不推荐
2. 重启电脑,推荐

1.4 make编译项目

在 建立的目录 执行命令:

mingw32-make -j8

这里 -j8 是使用多线程来进行编译,也可以 -j16, 速度会比单独执行 mingw32-make 命令快很多。

1.5 安装

继续在编译后的目录执行命令:

mingw32-make install

这一步最终生成的文件就会在之前配置CMAKE_INSTALL_PREFIX 目录中。
这里注意 install 是命令,而不是参数,之前我目录名字就是 install,导致我以为这一步是指定一个目录来存放最终文件

\x64\mingw\bin 存放动态链接库 libopencv_world3414.dll (运行的时候使用), 在\x64\mingw\lib 存放静态链接库 libopencv_world3414.dll.a(编译链接时使用)。

1.6 使用opencv库

编写一个简单的调用摄像头的 opencv 程序:

#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
namedWindow("test");
VideoCapture capture(0, CAP_DSHOW);
while (true)
{
Mat src;
capture >> src;
int width = src.cols;
int heigh = src.rows; imshow("test", src);
if (waitKey(10) == 27) break; }
destroyAllWindows();
return 0; }

然后使用命令行进行编译:

g++ 文件名 -I 头文件目录 -L 连接库目录 -lopencv_world3414.dll

这里简单介绍一下参数作用:
-I :(注意这里是i的大写,不是L的小写)指定头文件目录 ,也就是 include 目录。
-L :指定链接库目录,与后面 -lopencv_world配合,意思是去-L 目录去查找 链接库。
-lopencv_world3414.dll: (这里是-L的小写,不是i的大写)使用这个链接库,文件名字其实是libopencv_world3414.dll.a 而使用的时候就需要去掉后面 .a 和前面的 lib 然后与 -l连接。所有链接库的使用方法都遵循这个模式。其实这个模式是去掉后缀名的内容,如果前面有 lib 那么去掉 lib 然后与-l链接,如果没有就直接与连接。

命令执行后会生成 a.exe 文件,而这个文件执行就会提示没有
libopencv_world3414.dll , 所以可以把 dll 文件放入与 a.exe 同级目录就可以了。或者一劳永逸的方法,将 dll 文件目录添加到 path 环境变量中,推荐这种方法。

2.编译静态链接库

编译静态链接库的方法和编译动态链接库步骤基本相同,只是在使用编译好的opencv静态链接库的时候有一些麻烦。后面也会详细说明如果使用 opencv静态链接库。

2.1 配置参数

1.2 配置参数 这步中将 BUILD_SHARED_LIBS 选项取消勾选,然后其余步骤与 编译动态连接库的步骤相同,当然我还是建立了world。

2.2 编译后内容介绍

\x64\mingw\staticlib 存放所有静态链接库,此时bin目录中就没有 dll 文件了,因为我们没有生成动态链接库,所有函数实现都在静态链接库中。细心你会发现 libopencv_world3414.a 会比 libopencv_world3414.dll.a 大很多,因为里面 多了函数实现,而 libopencv_world3414.dll.a作用是告诉程序去调用 libopencv_world3414.dll,其中没有真正的函数实现,函数真正实现全在dll文件中。

除了 libopencv_world3414.a 静态链接库之外还有:

很多其它这些链接库,而这些库在项目编译链接的时候也是需要使用的(如果不建立world会产生更多)。

2.3 使用opencv

程序还是上面那个程序,命令有一些不同(需要链接很多东西):

g++ test3.cpp -I 头文件目录 -L 链接库目录 -lopencv_world3414 -lzlib -lIlmImf -llibjasper -llibjpeg-turbo -llibpng -llibprotobuf -llibtiff -llibwebp -lquirc -lzlib

参数作用已经链接库调用写法前面已经介绍了。

这条命令下去应该会有几千个错误。因为静态链接还要使用很多windows内置的静态链接库才能编译成功。所有这里比较麻烦,需要安装vc++才会有这些链接库。我安装的是 visual studio 2019, 所有链接库在目录D:\Windows Kits\10\Lib\10.0.19041.0\um\x86,最终命令:

g++ test3.cpp -I D:\mingw_opencv_static\include -L D:\mingw_opencv_static\x64\mingw\staticlib -lopencv_world3414 -lzlib  -L "D:\Windows Kits\10\Lib\10.0.19041.0\um\x86" -lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid   -lIlmImf -llibjasper -llibjpeg-turbo -llibpng -llibprotobuf -llibtiff -llibwebp -lquirc -lzlib

也就是添加了-lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 这些连接库,报出了一些警告但是还是可以编译成功的。

这里我最初找这些链接库是很麻烦的过程,看报错,列如:
undefined reference to __imp_CoCreateInstance 这个报错说明找不到 __imp_CoCreateInstance 这个函数,那么 Search all across Microsoft Docs 搜索这个函数,可以看到:

其存在于 Ole32.lib 这个静态连接库中,那么就在编译参数中加入这个静态链接库,所以我加入了 -lOle32

编译成功这个 a.exe 就可以脱离 dll 运行了。但是会比需要 动态链接库那个a.exe 的大很多,其实可以进一步精简:在源程序中引入的时候只引入你需要的头文件,然后不编译 opencv 库的时候不建立 world ,然后链接的时候就只引入你需要的链接库。

其它

如果你真是重头看到尾,我相信能理解很多东西。也能解决一些问题。

mingw编译opencv动态链接库和静态链接库及使用方法的更多相关文章

  1. [转载]GCC 编译使用动态链接库和静态链接库--及先后顺序----及环境变量设置总结

    来自http://blog.csdn.net/benpaobagzb/article/details/51364005 GCC 编译使用动态链接库和静态链接库 1 库的分类 根据链接时期的不同,库又有 ...

  2. GCC 编译使用动态链接库和静态链接库

    1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...

  3. GCC 编译使用动态链接库和静态链接库的方法

    1 库的分类 依据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的.所以生成的可执行文件就不受库的影响了.即使库被删除了,程序依旧能够成功执行. 有别于静态库,动态库的链接是在程 ...

  4. 【转】gcc 编译使用动态链接库和静态链接库

    1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...

  5. Linux下动态链接库和静态链接库

    第一部分:编译过程 先了解一下linux下C代码的编译过程,C代码的编译,一般分成四个阶段,包括:预编译,编译,汇编和链接,这四个阶段的分工是 预处理过程,负责头文件展开,宏替换,条件编译的选择,删除 ...

  6. Qt 共享库(动态链接库)和静态链接库的创建及调用

    前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...

  7. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  8. VS2010编译Boost 1.57 静态链接库

    http://www.cnblogs.com/cuish/p/4175491.html 0.前提 Boost库版本 1.57.0 下载地址 http://www.boost.org/users/his ...

  9. 利用GCC编译器生成动态链接库和静态链接库

    转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...

  10. Windows 下动态链接库和静态链接库

    1.静态链接库:就是在编译的时候把库中代码复制进工程中,导致工程变大,但是速度快. 缺点在于一套代码可能在内存中有多份拷贝,占用内存. 2.动态链接库:库由windos api加载库代码,内存中只有一 ...

随机推荐

  1. 腾讯云即时通信 IM 服务 实例项目

    腾讯云即时通信 IM 服务  https://github.com/tencentyun/TIMSDK

  2. CVE-2022-39197(CobaltStrike XSS <=4.7)漏洞复现

    最新文章更新见个人博客 漏洞说明 根据9.20日CobaltStrike官方发布的最新4.7.1版本的更新日志中介绍,<=4.7的teamserver版本存在XSS漏洞,从而可以造成RCE远程代 ...

  3. Security:如何安装 Elastic SIEM 和 EDR

    转载自:https://elasticstack.blog.csdn.net/article/details/114023944 需要学习的地方:生成SSL证书 图片结合最下方的代码文字使用 last ...

  4. 5.监控MySQL

    prometheus监控MySQL需要用到mysql_exporter. mysql_exporter 项目地址:https://github.com/prometheus/mysqld_export ...

  5. CSS-part1

    一. CSS选择器 1.css引入方式 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  6. 企业信息化建PLM系统、ERP系统、MES系统是单个逐步建设好,还是同时上比较好?

    企业信息化建PLM系统.ERP系统.MES系统肯定是单个逐步建设好啊,不仅仅是各个系统单独建设,系统内各模块的实施也应该先后逐步推进,切不可想着一口吃个大胖子,一股脑的全上,求全求快是很多系统实施失败 ...

  7. [题解] Codeforces 438 E The Child and Binary Tree DP,多项式,生成函数

    题目 首先令\(f_i\)表示权值和为\(i\)的二叉树数量,\(f_0=1\). 转移为:\(f_k=\sum_{i=0}^n \sum_{j=0}^{k-c_i}f_j f_{k-c_i-j}\) ...

  8. Ventoy制作PE启动盘

    前言 不怎么回事,只要是学计算机的都被非计算机专业的认为是会修电脑.常常抛来一个请求:咦,你不是学计算机的吗,帮我重装系统. 在日常生活中准备个有PE系统的U盘,以备不时之需. 常见的PE启动盘的制作 ...

  9. 它让你1小时精通RabbitMQ消息队列(新增死信处理)

    支持.NET/.NET Framework/.NET Core RabbitMQ作为一款主流的消息队列工具早已广受欢迎.相比于其它的MQ工具,RabbitMQ支持的语言更多.功能更完善. 本文提供一种 ...

  10. Python-D4-语法入门2

    目录 数据类型 数据类型之整型int 数据类型之浮点型float 数据类型之字符串str 数据类型之列表list 数据类型之字典dict 基本数据类型之布尔值bool 基本数据类型之元祖tuple 基 ...