云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

catch (ENV)——配置VSCode编译调试Visual Studio C++项目

jxf315 2025-02-26 12:32:42 教程文章 27 ℃

一。为什么放弃在Visual Studio IDE下Coding?

  1. PC有点拉跨,启动Visual Studio加载环境较慢,PC上装了多套VS,旧版本加载速度还行,但较新的版本如Visual Studio 2019,频繁地“无法响应并等待”太捉急
  2. VSCode是一款相当优秀的编辑器,有强大的插件支持,简单说就是在其下Coding,效率起飞
  3. 由于第2点描述,其他日常编码工作如shell脚本、golang等已全面切换至VSCode,想要All in One

二。那么,开始配置前,需要了解和做些什么?

  1. VSCode是且只是编辑器,虽然通过插件的支持可以进行构建和调试项目,但它不是IDE,它的天职是编辑,至于构建过程如编译链接就该给谁做就给谁做好了
  2. 安装VSCode与必要插件,

三。*踩坑摸索

  1. 网上查资料看有没类似案例,残念,要么大部分都是配置mingw,链接没点开直接弃;要么是按照VSCode官方配置MSVC,见Configure Visual Studio Code for Microsoft C++,概览后直接弃,单纯不喜欢,只想启动VSCode直接有个干净的开发环境,想写C++写C++,想写脚本写脚本,想让我通过开发环境命令行启动VSCode?不可能的;最后在一位国外老哥的一篇配置文章中,见https://dev.to/masoudr/build-and-debug-c-application-with-vscode-and-msvc-pfc,看到了些许希望,开坑
  2. 坑很大,填一个又来一个,边填边学,
  • 3个关键配置文件及其作用,lauch.json(调试启动用)、tasks.json(构建用)、c_cpp_properties.json(智能提示用),C/C++插件处理代码编写、构建、调试是三个相对独立的过程需分别看待
  • 国外老哥在构建即tasks.json中直接配置以shell方式启动cl.exe编译器,这个虽然和现有项目情况不大符,公司现有项目的VS工程不会废除(只有我想用VSCode,总不能搞事情让其他同事都不用VS吧),那么VSCode里配置的编译和链接参数就要和VS工程里的保持一致,这么多的参数写进tasks.json里实在是又繁琐又容易出错;但作为hello world是可以学习到配置机制的,这时踩的第一个坑就是"聪明蛋"(cmd)对空格及特殊符号的处理(cmd菜鸡表示太难用了),因为VSCode启动task时自动调用的是cmd /d /c [command],当然终端配置的是cmd,如果配置powershell,肯定调用的是不同的命令,这里不再验证;这个/c开关可要了命了,引号总会莫名其妙丢了,最终cmd /? 去找男人,原来

(可以在第一个引号前加@进行欺骗来规避,不再赘述踩坑流程)

  • 由于PC上存在多VS环境,所以一直有个念头是否加载了正确的构建环境,解决完空格问题后便开始验证,再次残念,国外老哥的build命令实际上是有问题的,

"buildCommand": "C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio\\2019\\Enterprise\\Common7\\Tools\\VsDevCmd.bat && cl"

他用&&连接命令,但实际上达不到他想要的效果。他是想先加载构建环境,加载成功后使用构建环境里的cl编译命令,但cl执行时,环境并未加载进来,可如此验证

打开cmd.exe,执行类似命令行语句(如使用PC上的VS2010环境)

这是正确加载到了构建环境的输出,注意cl的版本信息

重新打开cmd.exe(原先的cmd窗口里已存在构建环境,所以必须重新打开一个新的cmd窗口,这里也是容易疏忽踩坑的地方),再次执行命令行语句

cl却无法正确识别,说明cl执行时环境加载失败,原因未找到详细解释,应该和cmd批处理机制有关,未深究;实际上我一开始执行此命令是成功的,原因是安装VS2015的时候自动设置了PATH变量,所以cl调用的是VS2015的开发环境里cl命令,现在PATH里删除了该配置固报错,这也是前文提示注意cl版本信息的原因

尽管外国老哥的build命令存在问题,但却提供了构建思路,即先加载构建环境,然后调用构建工具,这也与VSCode官方方式通过开发环境cmd启动VSCode的描述相吻合;由于受到项目等种种约束,我这里的构建方式也明确下来了

  • VSCode启动定制的外部构建脚本,把构建工作交给脚本,脚本里调用VS工程命令行工具进行构建,这样因为VS工程文件必须存在,也就不必把繁琐的编译链接参数写进VSCode配置文件,但新增文件时就需要注意,一定要把它加进VS工程文件里
  • 构建的坑填完后,就是智能提示intellisense了,根据官方描述c_cpp_properties.json reference进行配置,这里主要是配置编译器路径(compilerPath)这个选项,配置后intellisense会查询编译器确定系统include目录以及预定义宏,由于PC上存在多VS环境,而对它的查询机制又不了解,能否查询到正确的include就是个未知数,而且VS2015与VS2019可以选择windows sdk版本,依赖的include路径是不同的,虽然可以在c_cpp_properties.json里配置windows sdk版本,但我填写VS2015里winsdk 8.1版本时,include路径是不对的,可在cpp里写个printf语句,然后看跳转到其函数声明文件路径即可判定,所以我放弃通过编译器查询,手撸,把include路径写进settings.json里,然后使用配置的值即可,是一次性配置,以后直接引用;确定这些路径也很简单,这里以VS2010为例,
  • 调试的坑主要就是输出内容到终端这个了,按照国外老哥的配置,只有程序运行结束时,才会把打印内容输出到调试控制台,这是无法接受的,可通过配置launch.json里的console值,把打印输出到其他终端来解决,我选择了externalTerminal,可根据需要调整这个值
  • 至此,与最终方案相关的坑就基本填完了,中间当然出现更多与此方案无关的坑,比如我曾试图通过调用编译链接器来完成构建,但配置的每个task都要单独加载构建环境,而不能统一加载进来供多个task共享,这个环境继承问题是插件不支持的;这些坑就不再赘述

四。开搞

1.编写外部构建脚本

  • 在PC上找到所需Visual Studio加载开发环境的启动脚本,我这里配置了项目常用的VS2010和VS2015
  • 环境加载调用:call /path/to/init/vc/env.bat
  • 构建命令调用:MSBuild …

2.settings.json配置自定义变量

  • 用户区(userspace settings)自定义变量,这里定义的变量几乎不会变动,一次性配置

主要关注几个使用绝对路径而未引用VSCode配置变量的地方,用来配置intellisense系统include,以及外部构建脚本build-vs.bat路径

  • 工作区(workspace settings)自定义变量,这里定义的变量随工程变动而变动

其中,

Project.Builder -- 使用哪个VS版本进行构建

Project.SlnFile -- 工程sln文件名,这里自动设置为工作目录名.sln,一般工程名与目录名相同

Project.Target -- 工程目标文件,这里自动设置为工作目录名.exe,一般目标文件名与目录名相同

Project.Include -- 工程include目录,会与系统配置的include目录一起配置intellisense的include路径

Project.Debug.CWD -- 调试程序启动时的当前工作目录,一般设置为生成最终目标文件的目录,如Debug,里面包含调试所需的pdb文件

Project.Debug.Program -- 调试目标程序名

Project.Debug.Args -- 目标程序的传参

Project.Debug.PreTask -- 调试程序启动前置task标识,根据tasks.json来设置

C_Cpp.default.* -- 用来配置intellisense相关配置,我这里是想把所有要变动的配置都配置在一个文件里,剩下的配置都是几乎不动的,所以写在settings.json里,当然都是可以配置进c_cpp_properties.json里的;如果想全都要,成,在c_cpp_properties.json配置项里使用${default}里引用C_Cpp.default相对应的值

3.tasks.json配置构建任务

这里配置构建task,以shell的形式执行外部构建脚本,其中,

label -- task标识

command -- 外部构建脚本,在userspace settings.json里配置的变量

args -- 外部构建脚本传参,在workspace settings.json里配置的相关变量

options->cwd -- 运行构建脚本时的当前工作目录,即工程目录,因为其包含了sln文件,这样就不用指定sln文件的绝对路径

4.launch.json配置调试启动

这里配置调试器启动配置,其中,

type -- cppvsdbg,windows c++调试器

request -- launch,启动,还可以配置attach,是附加到现有进程上去,这里不用

program -- 调试目标程序,在workspace settings.json里配置的变量

args -- 目标程序的传参,在workspace settings.json里配置的变量

cwd -- 调试程序启动时的当前工作目录,在workspace settings.json里配置的变量

environment -- 环境变量,如目标程序链接时是静态链接到dll的lib,而且dll又不在默认的搜索目录里,就需要把它所在的目录加入到环境变量里,不然启动目标程序的时候会因找不到dll而报错,具体追加环境变量的写法

preLaunchTask -- 调试程序启动前的前置task,在workspace settings.json里配置的变量

console -- 如果默认internalTerminal,在调试过程中的打印不会立即输出到终端上,需要等到程序运行结束才会输出;这里可选配置integratedTerminal,externalTerminal

5.*c_cpp_properties.json配置intellisense智能提示,根据官方文档配置即可,如果配置了C_Cpp.default.*,则这个文件不是必须的

6.运行调试

  • 运行,会启动前置build任务
  • 构建成功后,成功进入断点
  • F12查看printf函数原型,路径正确,说明intellisense正确加载了include,当然F11单步调试是调试不到这里的
  • 外部终端正确打印内容
  • 收工

五。资源

配置文件和案例见(
https://github.com/VVVylin/vsc-debug-vsproj-msbuild)

Tags:

最近发表
标签列表