用VSCode和CMake编写调试C/C++

这篇文章的首要目的是,通过配置VSCode,达到全平台的一致C/C++开发体验

对于编写C/C++的环境,我们至少需要有文本编辑器C/C++编译器,最好还能有C/C++调试器

VSCode本质上是一个文本编辑器,但是它有丰富的插件生态,通过插件我们可以对C/C++程序进行调试。而且,它拥有可自定义的任务系统,通过任务,可以封装一些操作,化繁为简。

如果谈编译器调试器的话,一般来讲,这两个东西是成双成对的,由gccg++编译的程序,使用gdb进行调试,由clang编译的程序使用lldb进行调试,由msvc编译的程序用msvc进行调试。除了msvc之外,其他的编译器调试器都是可以跨平台(Windows上通过Mingw实现)。 这几种编译器调试器占据了大部分市场,所以实际上也没得选,根据平台,LinuxGNUgccg++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.

到这里,梳理一下需要用到的东西。

  1. 文本编辑器:Visual Studio Code。
  2. C/C++编译器:gcc/g++(Linux)、clang(macOS)、msvc(Windows)。
  3. C/C++调试器:gdb(Linux)、lldb(macOS)、msvc(Windows)。
  4. 构建工具:CMake、Make。

下面说明环境的安装和配置步骤。

  1. 根据平台下载安装Visual Studio Code

  2. 打开VSCode,搜索安装扩展C/C++CMake

    1. C/C++。这个扩展的作用是C/C++代码提示和高亮、调试和代码文件关联跳转。
      vsccc.png
    2. CMake。这个扩展的作用是CMake语法提示和高亮。
      vsccmake.png
  3. 安装编译器和调试器。

    1. Windows
      下载并安装Visual Studio Community
      安装使用C++的桌面开发

      vscc.png

    2. Linux

      1. Debian系列(Debian/Ubuntu)

        sudo apt install gcc
        sudo apt install g++
        sudo apt install gdb
        sudo apt install make
        
      2. Redhat系列(RHEL/CentOS/Fedora)

        sudo yum install gcc
        sudo yum install g++
        sudo yum install gdb
        sudo yum install make
        
      3. 其它源码安装(自行搜索安装方式)

    3. macOS

      xcode-select --install
      
  4. 安装CMake

    1. Windows
      如果安装的Visual Studio Community版本大于2017,并选择了用于Windows的CMake工具,则不需要单独安装CMake

    2. Linux

      1. Debian系列(Debian/Ubuntu)

        sudo apt install cmake
        
      2. Redhat系列(RHEL/CentOS/Fedora)

        sudo yum install cmake
        
    3. macOS

      安装CMake需要用到brew,首先安装brew

      /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
      
      brew install cmake
      
    4. 也可以选择官网安装

      cmake.png

      根据平台下载并安装相应的安装包安装。

  5. 此时,所需要的工具都已经安装完毕。
    创建我们的C/C++项目文件夹,这里命名为CStart,并用VSCode打开该文件夹。
    新建下列文件结构

    CStart
    │—— CMakeLists.txt
    │—— main.c
    |—— .vscode
    │—— │—— launch.json
    │—— │—— tasks.json
    
  6. 使用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;
    }
    

    CMake简易教程

  7. 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++程序位置
                }
            }
        ]
    }
    
  8. 加入断点,左键单击即可,右键可以设置条件断点等。

    breakmain.png

  9. 按下F5VSCode开始执行launch.json的命令,在执行前会先运行preLaunchTask,编译C代码。
    终端界面可以看到编译的过程。

    build.png

    编译完成后,文件目录变成了这个样子,生成了Makefile文件和可执行文件还有调试信息,以及CMake缓存信息。
    files.png

    程序运行到断点处,如下图。
    break.png

    左侧为当前的变量信息,还有上边有调试的控制条,
    |继续|单步跳过|单步调试|单步跳出|重启|停止。
    切换到调试控制台界面,看到输出了库文件和调试信息加载过程。
    debug.png

    单击调试控制条的继续。输出Hello World,程序退出返回0。
    hello .png

  10. 有时候我们只想编译,不想运行程序,可以单独运行task: build_debug

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容