使用MinGW-w64编译opencv,并在CLion中使用opencv库
软件环境
最近需要使用到opencv,而目前使用的IDE是CLion,个人感觉体验挺好的,因此产生了在CLion上使用opencv库的需求。参考了网上几篇文章后,完成了相关配置,这里做个简单记录。首先给出自己的相关软件环境:
- windows 64位
- CMake 3.17.1
- MinGW-w64-x86_64-8.1.0-release-posix-seh-rt_v6-rev0
- opencv 4.2.0
- CLion 2019.3.2(自带的CMake版本为3.15.3)
顺便简单介绍下上述几者之间的关系:
- windows 64位是操作系统,软件是运行在该系统之上的;
-
CMake 3.17.1是帮助我们管理软件项目的编译与安装的工具,要编译opencv 4.2.0是需要
Makefile
的,但总不能拿着这个库自己去写Makefile吧,我们可以用CMake来方便的生成编译时需要的Makefile; -
MinGW-w64提供编译工具,编译软件需要编译器,而MinGW-w64将
GCC
的编译工具(如gcc
、g++
等)打包到一起,如此一来,我们只需要解压操作就能得到需要的一系列编译工具; - opencv 4.2.0是开源视觉库,写程序时要引用该库提供的函数,虽然可以获得其源码,但总不能每次编译都连带着库里的源文件一起吧,所以需要使用CMake为其生成Makefile,然后使用编译工具(本文使用的是MinGW-w64提供的编译工具)编译库中的源文件,得到相应的动态库。之后写自己的项目时,只需要opencv的头文件,并在编译时链接opencv相应模块的动态库即可(无需每次都编译库,效率高);
-
CLion是IDE,并且自带CMake用于管理我们通过该IDE建立的软件项目,这样就可以实现点击下编译按钮就能够完成编译,而无需操心幕后的工作。在CLion中写用到opencv的项目时,除了需要先编译opencv,还得在CLion项目下的
CMakeLists.txt
中添加一些内容,以指示编译的opencv的位置,这样CLion利用其自带的CMake进行编译时,就能够顺利找到相应的库从而进行链接。
参考的文章
网上相关的配置教程非常多,但有一些可能不太可行,我在配置时找到了两篇比较好的教程,亲测可行,这里直接给出链接:
遇到的问题
参照上述文章,从编译opencv到完成相关配置并跑通一个例程的过程中,我没有遇到什么棘手的问题,只有几个注意点值得一提:
问题1
编译过程中gcc
报错:
gcc: error: Dir\opencv-4.2.0\opencv\sources\modules\core\include: No such file or directory
......
这是因为目录中出现了空格,比如我把库的源码放在My[空格]Dir\opencv-4.2.0\opencv\sources
目录下,那么在编译时就会出现找库文件时把My[空格]
丢掉,只在Dir\xxx
里面找,这当然找不到了。至于具体是编译的哪个环节不支持目录名中的空格,我没有细究,解决这个问题只需要把空格去掉就好了:MyDir\xxx
。
问题2
编译过程中出现大量警告:
sources/modules/gapi/include/opencv2/gapi/own/saturate.hpp:75: warning: ignoring #pragma warning [-Wunknown-pragmas]
#pragma warning(default: 4244)
警告的意思是gcc
不认识预处理指令#pragma warning(default: 4244)
。在saturate.hpp
中有这么一段:
#ifdef _WIN32
// Suppress warning about converting x to floating-point
// Note that x is already floating-point at this point
#pragma warning(disable: 4244)
#endif
int ix = static_cast<int>(round(x));
#ifdef _WIN32
#pragma warning(default: 4244)
#endif
可能是opencv的这段代码没有充分考虑对多种编译器的支持,使用了某些编译器特有的预处理指令。这些警告并不要紧,不会影响编译的结果,忽视它们即可。
问题3
在CLion中新建一个项目,编写如下源码进行测试时:
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main() {
string pathname = R"(图片的pathname)";
Mat img = imread(pathname);
if (img.empty()) {
cout << "Error" << endl;
return -1;
}
namedWindow("pic", WINDOW_FULLSCREEN);
imshow("pic", img);
waitKey();
return 0;
}
链接时出现问题:warning LNK4272:库计算机类型“x64”与目标计算机类型“x86”冲突。这个问题已经很明显了,库被编译为了64位,而测试程序被编译为32位。根源在于CLion的工具链的设置,为CLion新增了MinGW工具链后,我的CLion共有2种工具链可选:
这时需要注意将MinGW设置为默认,否则就会出现用VS的编译器编译测试程序然后与MinGW编译得到的库进行链接的场景,这是要避免的,即便库和测试程序都被编译为64位也不要这样做,尽可能的保证我们的项目和使用的库采用同款同版本的编译器,这样能够避免一些问题。如果你的CLion只有MinGW一个编译器可选,那就没这个问题了。
当然,除了设置默认编译器之外,我们还可以通过CMake配置项中的工具链选项(Toolchain)来实现指定工具链: