文章目录
一、出发点
做项目用的一直是Visual Studio,但有的时候想要单独测试opencv中的某个函数,重新创建一个VS项目就过于冗余了,于是想在vscode中配置一个快速测试环境,本文就是这个过程的记录。
二、步骤
1.源码编译
直接下载的opencv中有使用vs studio编译好的opencv库,所以在vs中配置opencv比较简单;但这些库在vscode中没办法使用,需要用MinGW(Minimalist GNU for Windows)重新编译(但vscode好像也可以用vs的编译器吧),接下来介绍使用cmake-gui重新编译的方法。
1.1 cmake-gui生成makefile
- 设置源码路径(包含CMakelist的一个文件夹)和构建路径
- 点击configure后,对generator和compiler进行选择,等待一段时间
可以看到cmake-gui中出现了一堆配置参数,可以进行选择。举几个opencv中的
- BUILD_opencv_python:建立opencv python第三方库
- BUILD_SHARED_LIBS:勾选就是建立动态链接库,否则就是静态库
- BUILD_opencv_world:是否把链接库合并成一个world库
- 点击generate,结束之后可以看到设置的构建路径下会出现一个makefile文件,这个也是我们使用cmake的目的。我们目前还没有进行编译,生成的makefile其实只是指导编译器要如何编译。因此现在打开bin和lib里是没有东西的
- (补充)gcc/g++/make/cmake
- gcc和g++都是GNU下的编译工具,gcc用于c语言程序的编译,g++用于c++的编译
- 单个文件使用g++构建很方便
g++ main.cpp -o main
,但是多文件很折磨 - 然后出现了make工具,make根据用户编写的makefile进行构建
- makefile对于大工程很不方便,所以又出现了cmake,cmake根据CMakeList.txt生成makefile
- 除了cmake之外,还有qmake,它是根据.pro文件去生成makefile
1.2 编译
-
在makefile路径下打开终端,输入
mingw32-make -j8
(8是指线程数,可以加快编译速度,但设置太高容易电脑卡死,等到编译结束才会恢复) -
编译时候有可能会报关于mutex、thread、condition_variable的错误,原因在于mingw版本问题。
mingw有一个win32版本还有一个posix版本,其中posix版本对多线程有实现,所以将mingw版本更换为posix就可以编译通过了。 -
这步的结果是,在
\bin
文件夹下存放后缀为.dll的动态链接库(运行时候使用),在\lib
文件夹下存放后缀为.dll.a的静态链接库
链接库
上次有个疑问就是,为什么编译动态库的时候还会出来个静态库,这个静态库其实更讲究的名称应该叫动态库的引入库
不同编译器生成的引入库格式不同:
- .lib用于MSVC编译器
- .dll.a用于MinGW编译器(Minimalist GNU for Windows)
简单理解,引入库存的是声明,而.dll里边的是实现
2. vscode配置文件编写
2.1 c_cpp_properties.json
主要用来设置包含头文件的路径,设置 C/C++ 支持的版本号等等。
这里写的路径,代码补全的时候可以看见
{
"configurations": [
{
"name": "win",
"includePath": [
"${workspaceFolder}/**",
"D:\\opencv\\opencv\\build\\include",
"D:\\opencv\\opencv\\build\\include\\opencv2"
],
"defines": [],
"compilerPath": "C:\\ProgramFiles\\mingw64\\bin\\g++.exe",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
2.2 tasks.json
vscode中辅助程序编译的模块,自动化脚本,可以认为是在终端里写了一行g++命令
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "g++",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\bin\\${fileBasenameNoExtension}.exe",
"-I","D:\\opencv\\opencv\\build\\include",
"-L","D:\\opencv\\opencv\\build\\x64\\mingw\\lib",
"-l","opencv_world460.dll",
"-Wall",
//"-static-libgcc",
"-fexec-charset=GBK",
"-std=c++11"
],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "new"
},
"problemMatcher": "$gcc"
},
{
"label": "run",
"type": "shell",
"dependsOn": "build",
"command": "${fileDirname}\\bin\\${fileBasenameNoExtension}.exe",
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": true,
"panel": "new"
}
},
{
"type": "cppbuild",
"label": "C/C++: g++.exe 生成活动文件",
"command": "C:\\Program Files\\mingw64\\bin\\g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
}
]
}
3.launch.json
用于调试的配置文件
{
"version": "0.2.0",
"configurations": [
{
//这个大括号里是我们的‘调试(Debug)’配置
"name": "Debug", // 配置名称
"type": "cppdbg", // 配置类型,cppdbg对应cpptools提供的调试功能;可以认为此处只能是cppdbg
"request": "launch", // 请求配置类型,可以为launch(启动)或attach(附加)
"program": "${fileDirname}\\bin\\${fileBasenameNoExtension}.exe", // 将要进行调试的程序的路径
"args": [], // 程序调试时传递给程序的命令行参数,这里设为空即可
"stopAtEntry": false, // 设为true时程序将暂停在程序入口处,相当于在main上打断点
"cwd": "${fileDirname}", // 调试程序时的工作目录,此处为源码文件所在目录
"environment": [], // 环境变量,这里设为空即可
"externalConsole": false, // 为true时使用单独的cmd窗口,跳出小黑框;设为false则是用vscode的内置终端,建议用内置终端
"internalConsoleOptions": "neverOpen", // 如果不设为neverOpen,调试时会跳到“调试控制台”选项卡,新手调试用不到
"MIMode": "gdb", // 指定连接的调试器,gdb是minGW中的调试程序
"miDebuggerPath": "C:\\Program Files\\mingw64\\bin\\gdb.exe", // 指定调试器所在路径,如果你的minGW装在别的地方,则要改成你自己的路径,注意间隔是\\
"preLaunchTask": "build" // 调试开始前执行的任务,我们在调试前要编译构建。与tasks.json的label相对应,名字要一样
}]
}
c_cpp_properties.json里设置的include路径,与vscode里对路径的读取有关,这个路径设置出问题,include时候没法补全,并且编辑器内会显示找不到,但这时候调用task,是可以正常构建的
tasks.json里设置的路径,会影响构建,这个路径没设置对,就算编辑器里能读到文件,构建的时候会提示找不到文件
lib奇奇怪怪的,好像链接引入库或者直接链接动态库都能构建成功,-L后边的路径只是用于构建,而运行的时候还是会从默认路径中去搜索库,而不是从-L后边的路径搜索,要么将用到的.dll放在.exe的同级目录下,要么直接将bin路径设置成系统环境变量。这地方还是没搞懂,但现在反正是相对优雅了一点
3. g++/gcc语法学习(后边补充)
- -g:生成调试信息,该程序可以被调试器调试,不加-g 断点无法添加