以opencv作为开端,一直以来都是在vs上使用opencv,没有任何问题,但是近两天用vscode和mingw环境编译opencv相关项目时一直不成功,然后才了解到在使用不同的编译器,如vs、mingw编译的opencv,是不通用的,我们在opencv官网下载windows版本的opencv,结果是一个.exe的可执行文件,双击运行后得到的文件内容如下:
其中
-
build文件夹中是MSVC版本编译好的opencv,所以vs可以直接使用,但是mingw是不能使用的;
-
source文件夹中就是opencv的源码,(我也用mingw编译了源码,也从github上下载了别人编译好的mingw版本,可以成功编译项目,但是可执行程序执行后没有任何反应,也不报错)
- 这里再补充一下,编译完后的程序,在powershell中运行没有任何反应,用vscode也是一样,因为vscode里面也是会自动打开终端运行,而且打开的默认也是powershell。
- 然后我用cmd再来运行了下程序,运行就会报一个如下的错误,我确定我各种环境变量都添加了,也搜索了相关问题尝试了很多,还是没能解决,希望有会的人指点一下:
故既然vscode+mingw不能用msvc版本的opencv,那我就想办法用vscode+vs的环境使用这build文件中编译好的opencv不就行了,说干就干,摸索了好久好久,终于搞定。接下来进入正题(你电脑中一定要已经安装vs的环境):
补充,重要
:先把官方已经编译好的MSVC版本build中那个bin目录添加一个Path环境变量,大致是这个样子:
一定要,不然你能成功编译程序,但是在执行程序时,应该就会遇到一个这样的错误(同样,这个错误用poweshell执行,和上面说的一样没任何反应,也不会报错):
一、vscode基本环境
-
网上直接下载vscode,安装就好了,然后把vscode添加进环境变量:
类似于
D:\program files\Microsoft VS Code
,此目录里有Code.exe,添加进环境变量Path中
-
打开vscode后,搜索安装c++、cmake、cmake tools
二、代码准备
我拿了opencv的官方demo代码作为演示,路径是刚刚source下:sources\samples\cpp\example_cmake\
-
CMakeLists.txt的内容,做了部分删减:
cmake_minimum_required(VERSION 3.1)
project(opencv_example_project)
set(OpenCV_DIR “your_path/build/x64/vc15/lib”) # 这是我添加的一行,因为我没有把opencv添加环境变量,这里的build就是最开始截图的build,然后把your_path替换上去就好了
find_package(OpenCV REQUIRED)
add_executable(opencv_example example.cpp)
target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})
-
example.cpp中的内容,简单改了下:
#include <iostream> #include <string> #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" int main() { std::string window_name("girl"); cv::namedWindow(window_name); cv::resizeWindow(window_name, 640, 480); std::cout << "Built with OpenCV " << std::endl; cv::Mat image = cv::imread("../123.jpg"); cv::resize(image, image, cv::Size(640, 480)); cv::imshow(window_name, image); cv::waitKey(0); return 0; }
三、开始配置
-
最重要的一点:一定要先从开始菜单打开vs处理过的cmd,现在都差不多是64位机子了吧,记得用这:
若是从其它地方打开的cmd,也想初始化这个环境,可以在你电脑中搜索名为vcvars64.bat的脚本(它的路径类似于在这“D:\Program Files (x86)\MicrosoftVistualStudio\2017\Community\VC\Auxiliary\Build”),然后它拖进你打开的cmd,然后回车就可以了,
注意:千万不能使用powershell,就是不行,我当时被这个坑了很久。 -
在这样环境弄好的cmd里面输入
code
打开vscode,这也就是vscode要加环境变量的原因,如下: -
第2步后就得到类似如下的一个空白的vscode
-
然后再把刚刚准备的代码整个文件夹拖进到vscode来(我这里就是789文件夹),
-
然后选择trust,就如下了(因为写这里的时候,没有把图片放进来,所以这里的几张截图列表里都没有"123.jpg"):
-
开始cmake配置,键盘按下ctrl+shift+p,然后输入cmake
然后随便选一个环境好了,因为都不是,所以无所谓:
然后就会得到编译成功,会得到一个build文件夹,大概如下:
然后把build文件夹下,除了.cmake文件夹以外的文件都删除(上面说了不是我们要的),删除后大概是这样,记得一定只保留build下的.cmake文件夹:
-
自己在终端cmake、nmake编译:
-
cd build
-
输入命令
cmake -G "NMake Makefiles" ..
,可以看到cmake成功。 -
接着输入nmake进行编译,可以看到成功:
-
然后运行就能看到程序执行了
-
注意:
-
其实以上的操作在cmd命令行就可以完成,总结一下,打开有vs环境的cmd,进到代码所在文件夹,然后:
- mkdir build
- cd build
- cmake -G “NMake Makefiles” …
- nmake
以上就完成了操作,比vscode更加简单
-
但是之所以要用vscode,就是为了使用它的debug,下面讲解用vscode来进行debug。
四、debug的配置
-
看图依次点这三个位置:
然后选择cl.exe
-
配置tasks.json和launch.json
- 完成以上操作后,应该会报很多的错,但是都不要管,都关掉就好了,然后这边会多一个.vscode文件夹,里面有两个文件分别是tasks.json和launch.json。这里也可以自己去创建,
- 我建议就不要看系统生成的了,直接把我给的示例覆盖进去。
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "cl.exe - 生成和调试活动文件",
"type": "cppvsdbg",
"request": "launch",
// 记得修改这里的,路径一定写对
"program": "${workspaceFolder}/build/opencv_example.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"console": "externalTerminal",
"preLaunchTask": "C/C++: cl.exe 生成活动文件"
}
]
}
这里面有两个重要的项:
- “program”:这里的值要写到你的可执行文件的路径
- “preLaunchTask”:这里的值可以不修改,它需要与下面的tasks.json的一项值保持一致(下面会说)
- “args”:这一项就是放参数了,就是你的程序要执行时传入的参数,本例中不需要参数,就为空,如果有多个参数,就以逗号隔开,比如:“args”: ["-device", “0”],
tasks.json
{
"version": "2.0.0",
"options": {
"cwd": "${workspaceFolder}/build" // 注意这里是 workspaceFolder
},
"tasks": [
{
"label": "cmake",
"type": "shell",
"command": "cmake",
"args": [
"-G",
"'NMake Makefiles'",
".."
]
},
{
"label": "nmake",
"group": {
"kind": "build",
"isDefault": true,
},
"command": "nmake",
"args": [
]
},
{
"label": "C/C++: cl.exe 生成活动文件", // 这里和laubch.json的`preLaunchTask`值保持一致
"dependsOn": [
"cmake",
"nmake"
]
}
]
}
- 注意最后一个键为"label"的这个键值对, 一定与上述的launch.json的"preLaunchTask"的值保持一致;
- "options"的路径,都用build文件夹,一般不用改;
- 然后就是tasks中的任务:
- 一个cmake,带有args参数,就等于上面执行的cmake -G “NMake Makefiles” …;
- 一个nmake,不带有args参数,等于上面执行的nmake命令编译;
- 最后的"label"和"dependsOn"所在任务,就相当于把上面的两个任务以及launch.json联系起来了。
开始愉快debug
-
主函数下第一行按下F9打上断点,然后按F5开始debug,效果如下:
-
一直F10向下执行也是OK的,(但可能在debug到inshow()时会出点问题,但这就是本次要说明的问题了,而且这也无伤大雅)
说明:因为我们配置了launch.json和tasks.json,所以可以随意对代码进行修改直接按F5开始调试,vscode会帮我们自动去cmake和nmake编译,我们只需要专注于代码的修改调整就好。
五、小结
总结一下,大概分几步走:
-
下安装好vscode,并把vscode添加进环境变量,vscode中添加c++和cmake的扩展;
-
打开菜单栏中,在visual studio中选择类似于 “适用于 vs2017的x64本机工具命令提示“” ,就会打开一个cmd,然后在里面输入code打开vscode;
-
把你的代码所在文件夹整个拖进vscode,先ctrl+shift+p,输入cmake进行cmake,但是要把生成的build文件夹下除.cmake文件夹以外的文件都要删除;
-
然后在终端terminal中执行:
- cd build
- cmake -G “NMake Makefiles” …
- nmake
此时程序已经编译好了,就是用的msvc的环境,可以直接执行了。
-
开始debug,按照我给的两个示例json文件,按自己情况修改成适合自己的,如果你按照我的步骤来的,tasks.json应该是可以不用修改了,唯一要修改的就只有launch.json中键为"program"的值,因为生成的程序名不同,你要改成自己的程序的名字。
到这里就差不多了,此方法理论上针对任何cmake项目均可行(前提是需要第三方库的,你要自己先把第三方库准备好哦),以opencv为示例,但不局限于opencv哦。
如果你不会cmake,建议先github上小学习一下,这个cmake-example项目,就看看里面的“01-basic”就能很快入门的。代码比较简单的,也用不到第三方库的,CMakeLists.txt基本就两三行就能搞定。
最后再来看看程序的执行结果:
希望能对你有所帮助。
(2021.12.01)来更新一句:近来重装了系统,然后在GitHub上找到已经用MinGW编译好的,用的他的4.1.1版本,这次拉下来,能够使用mingw编译相关的opencv相关项目,也能正常使用了,所有又多了一种选择。