1. 这不是装个插件就完事的“环境配置”,而是C++开发者的第一道信任门槛
很多人点开“VS Code配置C++开发环境”这个标题,心里想的是:“不就是下个C/C++扩展、选个编译器、改两行json?十分钟搞定。”我试过——在某高校实验室带学生做嵌入式图像处理Demo时,让6个大三同学按网上最火的三篇教程操作,结果4人卡在launch.json路径报错,1人编译通过但调试断点完全不生效,还有1人连#include <vector>都标红提示找不到头文件。问题不在他们不会,而在于VS Code对C++的支持根本不是“开箱即用”,它是一套需要你亲手校准的精密仪器:编译器路径是它的燃料标号,c_cpp_properties.json是它的空气滤芯,tasks.json是它的点火时序,launch.json是它的油门响应曲线。任何一个参数偏差0.5%,整套系统就进入“看似运行、实则失能”的亚健康状态。这背后没有魔法,只有三件事必须搞清:你用的到底是什么编译器(GCC/Clang/MSVC)?它的标准库头文件藏在哪?调试器(GDB/LLDB/Windows Debugger)和编译器是否版本兼容?我见过太多人花三天调通Hello World,却在接入OpenCV时崩溃——因为c_cpp_properties.json里写的"intelliSenseMode": "gcc-x64",实际用的却是Clang编译器,IntelliSense直接“失明”。所以这篇不是教你怎么点菜单,而是带你把VS Code的C++引擎拆开,看清每个活塞怎么运动。适合两类人:刚从Dev-C++或Code::Blocks转过来、被VS Code的“轻量”宣传骗进来的新人;以及已经写过半年C++、但每次换项目都要重配环境、怀疑自己记性有问题的老手。接下来所有步骤,我都用某跨平台图像处理Demo的真实配置过程还原,连-std=c++17为什么不能写成-std=gnu++17这种细节,都会告诉你编译器文档第几页写的依据。
2. 编译器选择:别再无脑跟风“MinGW-w64”,你的项目真正需要的是什么?
2.1 三大编译器的本质差异:不是性能比拼,而是生态绑定
很多教程一上来就说“下载MinGW-w64”,仿佛这是Windows下C++开发的唯一真理。但真实情况是:你选的编译器,直接决定了后续90%的配置复杂度。我们来撕开这层包装纸:
MSVC(Microsoft Visual C++):Windows原生编译器,深度集成于Visual Studio。优势在于对Windows API、COM组件、DirectX等原生支持零延迟,生成的二进制体积小、运行快;劣势是跨平台几乎为零,且命令行工具链(
cl.exe)的参数风格与GCC/Clang完全不同,/std:c++17和-std=c++17这种基础语法都得重学。某公司做工业控制上位机软件时,因客户要求必须用MSVC编译,结果团队在VS Code里折腾两周才让tasks.json正确调用cl.exe,原因竟是cl.exe的输出日志格式不被VS Code默认解析器识别。GCC(GNU Compiler Collection):开源标杆,Linux/macOS默认编译器。优势是标准符合度高、社区文档全、对C++新特性支持激进;劣势是在Windows下需通过MinGW-w64或WSL桥接,头文件路径常出现
/mingw64/include/c++/11.2.0/这类混合斜杠,VS Code的IntelliSense极易误判。更关键的是,MinGW-w64官方提供两个分支:x86_64-posix-seh(推荐)和x86_64-win32-sjlj(已淘汰)。前者用SEH异常处理机制,与Windows原生一致;后者用SjLj(setjmp/longjmp),性能差且不支持C++异常。我曾见某导师的课程代码在win32-sjlj环境下编译通过,但throw std::runtime_error("test")直接导致程序崩溃——因为异常处理机制不匹配。Clang:LLVM项目产物,苹果macOS默认编译器。优势是错误提示极其人性化(比如把
vector<int> v = {1, 2, 3};写成vector<int> v{1, 2, 3};会明确告诉你“braced-init-list is not allowed here”),且与LLDB调试器天然协同;劣势是Windows下安装稍复杂,需手动配置clang++.exe路径,且某些Windows特有API(如CreateFileW)需额外链接-lkernel32。
提示:判断你当前编译器类型,打开终端执行
g++ --version或clang++ --version或cl,看输出首行。若显示g++ (MinGW-W64 x86_64-posix-seh, Built by...),说明是MinGW-w64;若显示clang version 15.0.7,则是Clang;若弹出Microsoft (R) C/C++ Optimizing Compiler Version...,则是MSVC。
2.2 实操验证:用一行命令揪出你的编译器“真身”
光看版本号还不够,必须验证编译器实际行为。新建一个test.cpp文件,内容如下:
#include <iostream> #include <string> int main() { std::string s = "hello"; std::cout << s.size() << std::endl; return 0; }然后在终端执行以下命令(注意替换为你实际的编译器路径):
# 对于MinGW-w64 g++ g++ -std=c++17 -v test.cpp -o test.exe 2>&1 | grep "ignoring nonexistent directory\|#include <...> search starts here" # 对于Clang clang++ -std=c++17 -v test.cpp -o test 2>&1 | grep "Selected GCC installation\|#include <...> search starts here" # 对于MSVC(需在Developer Command Prompt中运行) cl /std:c++17 /showIncludes test.cpp 2>&1 | findstr "Note"这个命令的关键在于-v(verbose)参数,它会强制编译器输出所有头文件搜索路径。例如MinGW-w64的输出中会有:
#include <...> search starts here: /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++ /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/x86_64-w64-mingw32 /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/backward /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include /mingw64/include /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include-fixed /mingw64/x86_64-w64-mingw32/include这些路径,就是你后续配置c_cpp_properties.json时"browse.path"和"includePath"的绝对依据。任何教程里写的“填入你的MinGW安装目录”都是模糊表述,必须用-v命令拿到精确路径。我曾帮某实验室学生排查,他按教程填了"C:/mingw64/include",但实际头文件在/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/下,导致<vector>一直标红。
2.3 配置决策树:根据你的项目类型,选最省心的编译器
别再凭感觉选编译器。用这张表快速决策:
| 你的项目需求 | 推荐编译器 | 关键理由 | VS Code配置难点 |
|---|---|---|---|
| 开发纯Windows桌面应用,需调用WinAPI或DirectX | MSVC | 无需额外安装,Visual Studio自带,cl.exe路径稳定为C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\bin\Hostx64\x64\cl.exe | tasks.json中args参数需用/而非-,如/std:c++17;c_cpp_properties.json中"intelliSenseMode"必须设为msvc-x64 |
| 跨平台开发(Windows+Linux),使用CMake构建 | Clang | Clang在Windows/Linux/macOS行为一致,且CMake对Clang的compile_commands.json生成最可靠 | 需手动下载Clang for Windows,clang++.exe路径需精确到bin目录,如C:/Program Files/LLVM/bin/clang++.exe |
| 学习算法竞赛、刷LeetCode,追求编译速度 | MinGW-w64 (x86_64-posix-seh) | 编译速度快,-O2优化效果好,且g++命令与Linux服务器环境一致 | c_cpp_properties.json中"compilerPath"必须指向g++.exe而非gcc.exe,否则IntelliSense无法识别C++标准库 |
注意:不要混用编译器!比如用MinGW-w64的
g++编译,却用MSVC的c1xx.dll调试——这会导致调试器完全无法加载符号表。某图像处理Demo曾因此出现“断点灰色不可用”,查了三天才发现.vscode/tasks.json里写的是g++,但.vscode/launch.json里"miDebuggerPath"却指向了C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/gdb.exe(这是个不存在的路径,MSVC根本不带gdb)。
3.c_cpp_properties.json:IntelliSense的“大脑地图”,90%的头文件标红问题出在这里
3.1 为什么#include <vector>会标红?真相是IntelliSense在“瞎找”
当你看到#include <vector>下方出现红色波浪线,VS Code提示“cannot open source file 'vector'”,第一反应往往是“是不是没装C/C++扩展?”——错。C/C++扩展只是载体,真正负责查找头文件的是IntelliSense引擎,而它的行动指南,就是.vscode/c_cpp_properties.json文件。这个文件不是可有可无的配置,它是IntelliSense的“大脑地图”,告诉它:“去哪找<vector>?<string>的定义在哪个文件夹?<windows.h>该不该忽略?”
IntelliSense的工作流程是:先读取c_cpp_properties.json里的"includePath"列表 → 按顺序扫描每个路径下的所有.h和.hpp文件 → 建立符号索引 → 最后高亮显示未找到的头文件。所以,标红的根本原因,永远是"includePath"里漏掉了某个关键路径,或者路径写错了格式。
3.2 手动构建includePath:从-v输出到JSON数组的完整映射
回到前面g++ -v命令的输出,我们提取出关键路径:
/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++ /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/x86_64-w64-mingw32 /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/backward /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include /mingw64/include /mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include-fixed /mingw64/x86_64-w64-mingw32/include现在,把这些Unix风格路径转换为Windows绝对路径,并填入c_cpp_properties.json。注意三个致命细节:
- 斜杠方向:VS Code在Windows下接受正斜杠
/或反斜杠\,但必须统一。推荐全部用正斜杠,避免C:\mingw64\include这种写法在JSON中需双反斜杠"C:\\mingw64\\include"的麻烦; - 末尾斜杠:路径末尾不能加
/,否则IntelliSense会认为这是个文件而非目录; - 通配符
**:"includePath"支持**通配符,但仅用于子目录递归,如"C:/mingw64/include/**"会扫描include下所有子文件夹,而"C:/mingw64/include"只扫描该层。
转换后的c_cpp_properties.json核心片段如下(以MinGW-w64为例):
{ "configurations": [ { "name": "Win64", "includePath": [ "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/x86_64-w64-mingw32", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/backward", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include", "C:/mingw64/include", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include-fixed", "C:/mingw64/x86_64-w64-mingw32/include", "${workspaceFolder}/**" ], "defines": [], "compilerPath": "C:/mingw64/bin/g++.exe", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "gcc-x64", "browse": { "path": [ "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/x86_64-w64-mingw32", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/backward", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include", "C:/mingw64/include", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include-fixed", "C:/mingw64/x86_64-w64-mingw32/include", "${workspaceFolder}" ], "limitSymbolsToIncludedHeaders": true, "databaseFilename": "${workspaceFolder}/.vscode/browse.vc.db" } } ], "version": 4 }注意:
"browse.path"必须与"includePath"严格一致,否则IntelliSense索引和代码浏览功能会脱节。某学生曾把"browse.path"少写了一行,结果F12跳转到<vector>定义时,打开的是一个空文件。
3.3intelliSenseMode:不是随便选的,它决定IntelliSense用哪套“方言”
"intelliSenseMode"字段常被忽略,但它至关重要。它的值不是随意填写的,而是VS Code预定义的枚举,对应不同编译器的ABI(应用二进制接口)和标准库实现。常见值及含义:
intelliSenseMode值 | 对应编译器 | 关键影响 |
|---|---|---|
"gcc-x64" | MinGW-w64 GCC | IntelliSense按GCC的ABI解析符号,如std::string的内存布局 |
"clang-x64" | Clang | 启用Clang特有的语义分析,如对auto推导更严格 |
"msvc-x64" | MSVC | 识别__declspec(dllexport)等Windows特有关键字,且<windows.h>头文件能正确展开 |
"gcc-arm64" | ARM64架构GCC | 用于嵌入式开发,如树莓派交叉编译 |
如果选错,后果很直接:std::vector<int>::size()方法可能不显示在智能提示中,或者#ifdef _WIN32宏定义失效。某跨平台图像处理Demo在切换Clang后,intelliSenseMode仍为gcc-x64,导致#include <sys/stat.h>(Linux头文件)被错误标记为“找不到”,因为IntelliSense以为这是GCC环境,却在Clang的头文件路径里找。
4.tasks.json:让VS Code真正“动手编译”,而不是假装在工作
4.1 为什么Ctrl+Shift+B编译失败?因为你没告诉VS Code“用谁编译、怎么编译”
tasks.json是VS Code的“执行引擎”,它定义了当你按下Ctrl+Shift+B(运行构建任务)时,VS Code具体要执行什么命令。很多人以为装了编译器就自动可用,其实VS Code对此一无所知——它就像一个司机,你必须给它一张清晰的路线图(tasks.json)和一辆指定的车(编译器路径)。
tasks.json的核心是"tasks"数组中的每个对象,其中最关键的三个字段:
"label":任务名称,显示在Ctrl+Shift+P>Tasks: Run Build Task菜单中,如"label": "g++ build active file";"command":编译器可执行文件的绝对路径,如"C:/mingw64/bin/g++.exe";"args":传递给编译器的参数数组,这是最容易出错的地方。
4.2args参数详解:从“Hello World”到专业项目的参数演进
以编译main.cpp为例,最简args是:
"args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}.exe" ]但这只能编译单文件。真实项目往往有多个.cpp文件、第三方库(如OpenCV)、自定义头文件路径。此时args需升级:
"args": [ "-g", // 生成调试信息,必加!否则launch.json无法调试 "-std=c++17", // 指定C++标准,必须与c_cpp_properties.json中cppStandard一致 "-I", "C:/opencv/build/install/include", // 添加OpenCV头文件路径 "-I", "${workspaceFolder}/include", // 添加项目自定义头文件路径 "${file}", // 当前活动文件 "${fileDirname}/*.cpp", // 编译同目录下所有cpp文件(注意:Windows cmd不支持通配符,需用PowerShell) "-L", "C:/opencv/build/install/x64/mingw/lib", // OpenCV库文件路径 "-lopencv_core455", // 链接OpenCV core库(版本号需匹配) "-lopencv_imgproc455", "-o", "${fileDirname}/${fileBasenameNoExtension}.exe" ]这里有两个深坑:
通配符
*.cpp在Windows CMD下无效:"${fileDirname}/*.cpp"在CMD中会被当作字面量字符串,导致g++报错“no input files”。解决方案是改用PowerShell作为终端:"options": { "shell": { "executable": "powershell.exe", "args": ["-NoProfile", "-ExecutionPolicy", "Bypass"] } }库链接顺序不能错:
-lopencv_core455必须写在-lopencv_imgproc455之后,因为imgproc依赖core。如果顺序颠倒,链接器会报undefined reference to 'cv::Mat::Mat()'——这是典型的符号未定义错误,根源是链接器从左到右扫描,遇到imgproc里引用的core符号时,core库还没被加载。
4.3 多文件项目实战:用make替代硬编码args,一劳永逸
当项目超过5个.cpp文件,硬编码args会变成噩梦。此时应引入make——它才是C++项目的“编译指挥官”。在项目根目录创建Makefile:
# Makefile CXX = g++ CXXFLAGS = -g -std=c++17 -I./include -I./third_party/opencv/include LDFLAGS = -L./third_party/opencv/lib LDLIBS = -lopencv_core455 -lopencv_imgproc455 -lopencv_highgui455 TARGET = image_processor.exe SOURCES = $(wildcard src/*.cpp) OBJECTS = $(SOURCES:.cpp=.o) $(TARGET): $(OBJECTS) $(CXX) $(LDFLAGS) $^ -o $@ $(LDLIBS) %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ .PHONY: clean clean: rm -f $(OBJECTS) $(TARGET)然后tasks.json只需调用make:
{ "version": "2.0.0", "tasks": [ { "label": "make build", "type": "shell", "command": "make", "group": "build", "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared", "showReuseMessage": true, "clear": true }, "problemMatcher": ["$gcc"] } ] }problemMatcher: ["$gcc"]是关键——它让VS Code能解析g++的错误输出,把main.cpp:12:10: error: 'vector' was not declared in this scope这样的错误,精准定位到main.cpp第12行。没有它,编译错误只会显示在终端里,无法跳转。
5.launch.json:调试不是“点一下就断”,而是让调试器和编译器说同一种语言
5.1 断点灰色不可用?先检查miDebuggerPath和MIMode
launch.json是VS Code的“调试协议翻译器”,它把VS Code的调试指令(如“在第15行设断点”)翻译成调试器(GDB/LLDB)能听懂的命令。如果断点灰色,90%是因为翻译失败。核心字段:
"miDebuggerPath":调试器可执行文件的绝对路径。MinGW-w64自带gdb.exe,Clang自带lldb.exe,MSVC用WindowsDebugger(无需路径);"MIMode":指定调试器类型,"gdb"、"lldb"或"cppvsdbg"(MSVC);"program":要调试的可执行文件路径,必须与tasks.json中-o参数生成的路径完全一致。
常见错误配置:
// ❌ 错误:路径指向了MinGW的gdb,但编译器用的是Clang "miDebuggerPath": "C:/mingw64/bin/gdb.exe", "MIMode": "gdb", // ✅ 正确:Clang配LLDB "miDebuggerPath": "C:/Program Files/LLVM/bin/lldb.exe", "MIMode": "lldb",5.2preLaunchTask:让调试前自动编译,消灭“修改代码后忘记编译”的低级错误
"preLaunchTask"字段是launch.json的灵魂。它确保每次点击绿色三角形启动调试前,VS Code先执行一次构建任务。配置如下:
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/${fileBasenameNoExtension}.exe", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "C:/mingw64/bin/gdb.exe", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "g++ build active file", // 必须与tasks.json中label完全一致 "internalConsoleOptions": "neverOpen" } ] }"preLaunchTask": "g++ build active file"这一行,让VS Code在调试前自动运行tasks.json中label为"g++ build active file"的任务。这样,你改完main.cpp,直接F5,VS Code会先编译,再启动调试器——彻底告别“代码改了但还在跑旧版本”的尴尬。
5.3 调试器高级技巧:用setupCommands解锁GDB的隐藏能力
"setupCommands"数组允许你在GDB启动后、程序运行前,执行GDB原生命令。这能解决很多痛点:
- 启用漂亮打印(Pretty Printing):让
std::vector、std::map等容器在调试窗口显示为可读格式,而非一堆指针地址。上面的"-enable-pretty-printing"就是干这个的; - 设置环境变量:某些库(如OpenCV)需要
OPENCV_DIR环境变量才能加载DLL,可在setupCommands中添加:{ "description": "Set OpenCV environment variable", "text": "set environment OPENCV_DIR=C:/opencv/build/install", "ignoreFailures": true } - 忽略SIGPIPE信号:网络编程中常遇到
SIGPIPE导致调试中断,添加:{ "description": "Ignore SIGPIPE", "text": "handle SIGPIPE nostop noprint pass", "ignoreFailures": true }
注意:
setupCommands中的text字段必须是GDB命令,不是Shell命令。"set environment"是GDB命令,而"export OPENCV_DIR=..."是Shell命令,无效。
6. 终极验证:用一个真实图像处理Demo,跑通从编辑、编译到调试的全链路
6.1 Demo结构:模拟某高校图像处理课程的最小可行项目
我们用一个真实的、非玩具的场景来验证所有配置:某高校图像处理课程的“灰度直方图均衡化”Demo。项目结构如下:
image_processor/ ├── .vscode/ │ ├── c_cpp_properties.json │ ├── tasks.json │ └── launch.json ├── include/ │ └── image_utils.h // 自定义头文件 ├── src/ │ ├── main.cpp // 主程序 │ └── image_utils.cpp // 图像处理函数实现 ├── assets/ │ └── lena.jpg // 测试图片 └── Makefilemain.cpp核心逻辑:
#include <iostream> #include <opencv2/opencv.hpp> #include "image_utils.h" // 自定义头文件 int main() { cv::Mat img = cv::imread("assets/lena.jpg"); if (img.empty()) { std::cerr << "Failed to load image!" << std::endl; return -1; } cv::Mat equalized; equalize_histogram(img, equalized); // 调用自定义函数 cv::imshow("Original", img); cv::imshow("Equalized", equalized); cv::waitKey(0); return 0; }6.2 全链路配置清单:每一步都对应前文原理
现在,我们把前文所有知识点,浓缩成一份可直接复制粘贴的配置清单:
1.c_cpp_properties.json(关键路径已替换为你的实际路径)
{ "configurations": [ { "name": "Win64", "includePath": [ "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/x86_64-w64-mingw32", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/backward", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include", "C:/mingw64/include", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include-fixed", "C:/mingw64/x86_64-w64-mingw32/include", "C:/opencv/build/install/include", "${workspaceFolder}/include", "${workspaceFolder}/**" ], "defines": [], "compilerPath": "C:/mingw64/bin/g++.exe", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "gcc-x64", "browse": { "path": [ "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/x86_64-w64-mingw32", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/backward", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include", "C:/mingw64/include", "C:/mingw64/lib/gcc/x86_64-w64-mingw32/11.2.0/include-fixed", "C:/mingw64/x86_64-w64-mingw32/include", "C:/opencv/build/install/include", "${workspaceFolder}/include", "${workspaceFolder}" ], "limitSymbolsToIncludedHeaders": true, "databaseFilename": "${workspaceFolder}/.vscode/browse.vc.db" } } ], "version": 4 }2.tasks.json(使用Makefile驱动)
{ "version": "2.0.0", "tasks": [ { "label": "make build", "type": "shell", "command": "make", "group": "build", "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared", "showReuseMessage": true, "clear": true }, "problemMatcher": ["$gcc"] } ] }3.launch.json(GDB调试,自动编译)
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/image_processor.exe", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "C:/mingw64/bin/gdb.exe", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set OpenCV environment variable", "text": "set environment OPENCV_DIR=C:/opencv/build/install", "ignoreFailures": true } ], "preLaunchTask": "make build", "internalConsoleOptions": "neverOpen" } ] }4.Makefile(支持多文件、库链接)
CXX = g++ CXXFLAGS = -g -std=c++17 -I./include -I./third_party/opencv/include LDFLAGS = -L./third_party/opencv/lib LDLIBS = -lopencv_core455 -lopencv_imgproc455 -lopencv_highgui455 TARGET = image_processor.exe SOURCES = $(wildcard src/*.cpp) OBJECTS = $(SOURCES:.cpp=.o