用VSCode和CMake编写调试C/C++
这篇文章的首要目的是,通过配置VSCode
,达到全平台的一致C/C++开发体验。
对于编写C/C++的环境,我们至少需要有文本编辑器、C/C++编译器,最好还能有C/C++调试器。
VSCode
本质上是一个文本编辑器,但是它有丰富的插件生态,通过插件我们可以对C/C++程序进行调试。而且,它拥有可自定义的任务系统,通过任务,可以封装一些操作,化繁为简。
如果谈编译器和调试器的话,一般来讲,这两个东西是成双成对的,由gcc
和g++
编译的程序,使用gdb
进行调试,由clang
编译的程序使用lldb
进行调试,由msvc
编译的程序用msvc
进行调试。除了msvc
之外,其他的编译器调试器都是可以跨平台(Windows上通过Mingw
实现)。 这几种编译器和调试器占据了大部分市场,所以实际上也没得选,根据平台,Linux
下GNU
的gcc
、g++
和gdb
是主流,macOS
下,clang
+lldb
是主流,使用GNU
的也不能算少。Windows
平台下比较复杂,主要有两种,一种是通过Mingw
使用gcc
的,另一种则是使用微软出品的宇宙最强IDEVisual Studio
。
上面提到全平台的一致C/C++开发体验,但是不同编译器、调试器的使用方式并不相同。调试器的问题,VSCode
通过C/C++
插件已经解决了。而编译器的问题,需要一个通用的编译构建工具,通过CMake
生成Makefile
并编译。
CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice.
到这里,梳理一下需要用到的东西。
- 文本编辑器:Visual Studio Code。
- C/C++编译器:gcc/g++(Linux)、clang(macOS)、msvc(Windows)。
- C/C++调试器:gdb(Linux)、lldb(macOS)、msvc(Windows)。
- 构建工具:CMake、Make。
下面说明环境的安装和配置步骤。
-
根据平台下载安装Visual Studio Code。
-
打开
VSCode
,搜索安装扩展C/C++
和CMake
。-
C/C++
。这个扩展的作用是C/C++代码提示和高亮、调试和代码文件关联跳转。
vsccc.png -
CMake
。这个扩展的作用是CMake语法提示和高亮。
vsccmake.png
-
-
安装编译器和调试器。
-
Windows
vscc.png
下载并安装Visual Studio Community 。
安装使用C++的桌面开发。
-
Linux
-
Debian系列(Debian/Ubuntu)
sudo apt install gcc sudo apt install g++ sudo apt install gdb sudo apt install make
-
Redhat系列(RHEL/CentOS/Fedora)
sudo yum install gcc sudo yum install g++ sudo yum install gdb sudo yum install make
-
其它源码安装(自行搜索安装方式)
-
-
macOS
xcode-select --install
-
-
安装CMake。
-
Windows
如果安装的Visual Studio Community
版本大于2017,并选择了用于Windows的CMake工具,则不需要单独安装CMake
。 -
Linux
-
Debian系列(Debian/Ubuntu)
sudo apt install cmake
-
Redhat系列(RHEL/CentOS/Fedora)
sudo yum install cmake
-
-
macOS
安装CMake需要用到brew,首先安装
brew
。/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install cmake
-
也可以选择官网安装
cmake.png
根据平台下载并安装相应的安装包安装。
-
-
此时,所需要的工具都已经安装完毕。
创建我们的C/C++项目文件夹,这里命名为CStart
,并用VSCode打开该文件夹。
新建下列文件结构CStart │—— CMakeLists.txt │—— main.c |—— .vscode │—— │—— launch.json │—— │—— tasks.json
-
使用CMake构建C/C++项目
CMakeLists.txt 项目cmake配置文件。关于CMakeLists.txt的编写,展开来讲有点长,可以到网上搜索相关教程。这是一个最简单的版本。通过这个文件,统一全平台下的项目管理与构建配置。cmake_minimum_required (VERSION 2.8) #最低要求的CMake版本 project(CStart) # 项目名称 file(GLOB SRC_FILE *.c) # 建立变量SRC_FILE为目录下.c文件列表 add_executable (${PROJECT_NAME} ${SRC_FILE}) # 要求编译可执行文件
main.c 简单的HelloWorld代码
#include <stdio.h> int main(void) { printf("Hello world\n"); return 0; }
-
VSCode配置编译任务与调试对象
在配置的时候会用到一些vscode的变量,用${}
包裹起来的那些。
${workspaceFolder}
是当前工作空间(或vscode所打开根文件夹)在操作系统中绝对路径
${workspaceFolderBasename}
是当前工作空间(或vscode所打开根文件夹)的名称tasks.json 这是
VSCode
任务的配置文件,通过配置它可以快速执行各种命令。这里我们利用它来配置编译构建流程。我们要执行的任务为建立build文件夹,在build文件夹中使用CMake生成并编译。通过这个任务配置,统一全平台下的程序编译命令。{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { // 在根文件夹中执行创建文件夹build的命令 // 除windows系统外执行的命令为`mkdir -p build` // windows系统是在powershell中执行命令`mkdir -Force build` "label": "build_dir", "command": "mkdir", "type": "shell", "args": [ "-p", "build" ], "windows": { "options": { "shell": { "executable": "powershell.exe" } }, "args": [ "-Force", "build" ], } }, { // 在build文件夹中调用cmake进行项目配置 // 除windows系统外执行的命令为`cmake -DCMAKE_BUILD_TYPE=<Debug|Release|RelWithDebInfo|MinSizeRel> ../` // windows系统是在visual stuido的环境中执行命令`cmake -DCMAKE_BUILD_TYPE=<Debug|Release|RelWithDebInfo|MinSizeRel> ../ -G "CodeBlocks - NMake Makefiles"` "label": "cmake", "type": "shell", "command": "cmake", "args": [ "-DCMAKE_BUILD_TYPE=${input:CMAKE_BUILD_TYPE}", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", // 生成compile_commands.json 供c/c++扩展提示使用 "../" ], "options": { "cwd": "${workspaceFolder}/build", }, "windows": { "args": [ "-DCMAKE_BUILD_TYPE=${input:CMAKE_BUILD_TYPE}", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", "../", "-G", "\"CodeBlocks - NMake Makefiles\"" ], "options": { "shell": { // "executable": "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat", // 需要根据安装的vs版本调用vs工具命令提示符 "executable": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat", "args": [ "${input:PLATFORM}", //指定平台 "-vcvars_ver=${input:vcvars_ver}", //指定vc环境版本 "&&" ] } }, }, "dependsOn": [ "build_dir" // 在task `build_dir` 后执行该task ] }, { // 在build文件夹中调用cmake编译构建debug程序 // 执行的命令为`cmake --build ./ --target all --` // windows系统如上需要在visual stuido的环境中执行命令 "label": "build", "group": "build", "type": "shell", "command": "cmake", "args": [ "--build", "./", "--target", "all", "--" ], "options": { "cwd": "${workspaceFolder}/build", }, "problemMatcher": "$gcc", "windows": { "options": { "shell": { // "executable": "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat", "executable": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat", "args": [ "${input:PLATFORM}", "-vcvars_ver=${input:vcvars_ver}", "&&" ] } }, "problemMatcher": "$msCompile" }, "dependsOn": [ "cmake" // 在task `cmake` 后执行该task ] } ], "inputs": [ { "id": "CMAKE_BUILD_TYPE", "type": "pickString", "description": "What CMAKE_BUILD_TYPE do you want to create?", "options": [ "Debug", "Release", "RelWithDebInfo", "MinSizeRel", ], "default": "Debug" }, { "id": "PLATFORM", "type": "pickString", "description": "What PLATFORM do you want to create?", "options": [ "x86", "amd64", "arm", "x86_arm", "x86_amd64", "amd64_x86", "amd64_arm", ], "default": "amd64" }, { "id": "vcvars_ver", "type": "pickString", "description": "What vcvars_ver do you want to create?", "options": [ "14.2", // 2019 "14.1", // 2017 "14.0", // 2015 ], "default": "14.2" } ] }
launch.json 这是
VSCode
运行调试的配置文件。全平台统一的调试体验就靠它了。依赖于VSCode的C/C++扩展。这里需要告诉VSCode你的C/C++程序在哪,以及运行参数,工作目录等,用哪个调试器调试。{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Launch Debug", //名称 "type": "cppdbg", //调试类型,除使用msvc进行调试外,均为该类型 "request": "launch", "program": "${workspaceFolder}/build/${workspaceFolderBasename}", //指定C/C++程序位置 "args": [], //指定运行参数 "stopAtEntry": false, "cwd": "${workspaceFolder}", //指定工作目录 "preLaunchTask": "build", //在调试前会先调用build_debug这个task编译构建程序 "environment": [], "externalConsole": false, "osx": { //macOS的特定配置 // "miDebuggerPath": "/Applications/Xcode.app/Contents/ Developer/usr/bin/lldb-mi", //修改使用的lldb-mi,一般不需要修改 "MIMode": "lldb" //指定使用lldb进行调试 }, "linux": { //linux的特定配置 "MIMode": "gdb", //指定使用gdb调试 "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, "windows": { //windows的特定配置 "type": "cppvsdbg", //指定使用msvc进行调试 "program": "${workspaceFolder}/build/${workspaceFolderBasename}.exe", //指定C/C++程序位置 } } ] }
-
加入断点,左键单击即可,右键可以设置条件断点等。
breakmain.png
-
按下
build.pngF5
,VSCode
开始执行launch.json
的命令,在执行前会先运行preLaunchTask
,编译C代码。
终端界面可以看到编译的过程。
编译完成后,文件目录变成了这个样子,生成了Makefile文件和可执行文件还有调试信息,以及CMake缓存信息。
files.png
程序运行到断点处,如下图。
break.png
左侧为当前的变量信息,还有上边有调试的控制条,
|继续|单步跳过|单步调试|单步跳出|重启|停止。
切换到调试控制台
界面,看到输出了库文件和调试信息加载过程。
debug.png
单击调试控制条的继续。输出Hello World
,程序退出返回0。
hello .png -
有时候我们只想编译,不想运行程序,可以单独运行
task: build_debug
。