写作原因

  • 微软的 VSCode 一直以来为人诟病的一个问题就是对于 C/C++ 工程的编译以及调试支持度有限,配置起来比较复杂,但是 vscode-cpptools 团队经过一段时间的 bug 修复之后,为我们带来了众多新特性
  • 截止到本文作成时 (2017-8-4) 此扩展已经更新到 0.12.1 版本,经过尝试使用,新版本对于 C/C++ 的支持有了很大提升,但目前中文博客很少有提到如何使用新版的 vscode-cpptools,而旧版与新版之间的区别也比较明显,所以这里记录一个 C/C++ 工作环境配置方案以供参考

面向的问题

  • 一直以来,写一个小型的 C/C++ 代码工程是非常令人头疼的一件事,比如有一个只有几个源文件的代码工程需要编辑和编译:

    • 打开 IDE 进行编辑,会有种杀鸡焉用牛刀的感觉,本可以在 IDE 打开的过程中就完成修改和编译工作
    • 使用代码编辑器配合命令行进行编译,如果代码有配合 Makefile,那么编译不成问题,但是调试又是一个麻烦,命令行下的调试工具没有那么直观,学习起来也很耗费时间
  • 所以能不能做个折衷,直接在轻量级的代码编辑器完成编辑、编译、调试的工作呢?直到最近 vscode-cpptools 做了大量更新,这个想法才得以更好地实现

准备工作

工具准备

  1. 安装 VS Code: 由于我们这里记录的是工具配置,所以暂不介绍安装流程,但相信点进这篇博客的读者具备安装工具的能力,或者已经安装好了 VS Code
  2. 安装 vscode-cpptools: 在 VS Code 的插件安装栏中搜索 C/C++ 即可找到微软官方出品的这个工具,根据指引安装并重载窗口即可
  3. 编译工具安装: 一般来讲在 VS Code 中进行开发并不涉及编译工具版本,但是由于其对 Clang 的支持比较好,我推荐有能力的读者安装 Clang ,当然其他的任何编译工具都是可以的,包括 GCC,MSVC等
    • 但是这里不得不提的一点是,在 Windows 下安装 Clang 是一件不太愉快的事情,如果您在安装时遇到困难,大可放弃安装 Clang ,转而安装 GCC
    • 本文讲解的内容是在 Windows 下实现的,在其他系统当中仅需对工具目录等进行简单的修改即可复现这个过程

方案选择

  • 根据应用环境不同,本文提出两种解决 C/C++ 工作环境配置的方案:

    1. 第一种是完全依赖 VS Code 的解决方案,即只使用其内置工具实现工作环境配置。这种方案比较简单,但是对于代码的迁移和扩展造成了一定的困扰。
    2. 第二种是 VS Code 配合 Makefile 的解决方案,即使用 VS Code 的代码编辑功能,配合 Makefile 的编译支持来配置工作环境。相对第一种解决方案,这种方案更适合代码的迁移
      • 例如代码从 Windows 平台的 VS Code 中迁移到服务器的 Linux 命令行下时,可以在 Windows 中使用 VS Code 来编辑和编译,将代码迁移后在 Linux 下使用 Makefile来编译

方案一:VS Code 原生工具编译

1. 新建测试工程

首先新建一个文件夹 VSC-CPP 并编写几个源文件,作为测试样例

这个工程包含五个文件,包括两对 .cpp + .h 的函数声明与实现,以及一个调用这两个函数的 main.cpp

目录结构

- add.h     // add() 函数声明
- add.cpp // add() 函数实现
- sub.h // sub() 函数声明
- sub.cpp // sub() 函数实现
- main.cpp // 调用 add() 与 sub()
  • add.h:
#ifndef _ADD_H_
#define _ADD_H_ int add(int a, int b);

endif // ! ADD_H

  • add.cpp:
#include "add.h"

int add(int a, int b) { return a + b; }
  • sub.h:
#ifndef _SUB_H_
#define _SUB_H_ int sub(int a, int b);

endif // ! SUB_H

  • sub.cpp:
#include "sub.h"

int sub(int a, int b) { return a - b; }
  • main.cpp:
#include "add.h"
#include "sub.h"
#include <iostream> int main() {

std::cout << add(1, 2) << std::endl;

std::cout << sub(2, 1) << std::endl;

return 0;

}

2. 配置环境

首先假定我们使用的编译工具如下:

  1. 编译工具:g++
  2. 调试工具:gdb
  • 在 VS Code 中打开工具窗口 (默认Ctrl+Alt+P) ,输入 C/CPP: Edit Configurations来生成配置文件

  • 然后在自动打开的c_cpp_properties.json中配置 Include路径等内容 (一般而言自动生成的就是可用的,但是 Windows 下可能需要额外配置)

  • 上一步结束后,一些 C/C++ 的代码提示等功能应该就可以正常工作了,接下来我们让 VS Code 能处理编译工作
  • 打开工具窗口 (默认Ctrl+Shift+P) → \rightarrow" role="presentation">→→ \rightarrow→ 输入Tasks: Configure Task Runner,弹出窗口中选择 Others (这里是假定我们要用 GCC 来编译,如果使用 MSBuild 做这项工作,那么可以直接选择 MSBuild 选项) → \rightarrow" role="presentation">→→ \rightarrow→ 在新打开的tasks.json中配置如下 注意:复制这段代码的时候请删除其中的注释,否则可能会报错
    • task.json:
{
"version": "2.0.0",
"tasks": [
{
// 默认第一条为编译命令
"taskName": "build",
// 使用 g++ 编译
"command": "g++",
// 参数包含所有使用到的源文件
"args": [
"main.cpp",
"add.cpp",
"sub.cpp",
"-o",
"main.exe"
],
// 默认在 shell 中执行编译命令
"type": "shell"
},
{
// 编译 debug 用的目标文件
"taskName": "build-debug",
"command": "g++",
// -g 参数用于编译可 debug 的目标文件
"args": [
"-g",
"main.cpp",
"add.cpp",
"sub.cpp",
"-o",
"debug.exe"
],
"type": "shell"
}
]
}
  • 至此代码应该可以正常编译了:打开工具窗口 (默认Ctrl+Alt+P) → \rightarrow" role="presentation">→→ \rightarrow→ 输入Tasks: Run Tasks → \rightarrow" role="presentation">→→ \rightarrow→ 此时应该已经可以看到两个不同的任务,分别为 buildbuild-debug,与上一步定义的相同

  • 选择 build 并执行输出得到的目标文件即可看到结果,说明编译执行是正确无误的

  • 接下来尝试对代码进行调试,进入调试窗口 → \rightarrow" role="presentation">→→ \rightarrow→ 点击调试配置按钮 (如图中红圈所示)

  • 选择 C++(GDB/LLDB) (如果使用 MSVC 编译,可以选择C++(Windows)) → \rightarrow" role="presentation">→→ \rightarrow→ 此时会生成调试配置文件 launcher.json

  • 使用配置如下,根据您的具体系统环境进行修改

{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
// g++ -g 生成的调试用目标文件名
"program": "${workspaceRoot}/debug.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
// 输入 gdb 的路径 (有些情况下需要绝对路径)
"miDebuggerPath": "gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
// task.json 中指定的调试目标文件编译命令
// 这样可以在调试前免去手动执行 build-debug 的一步
"preLaunchTask": "build-debug"
}
]
}
  • 在源文件中添加一个断点,点击调试界面中的开始调试按钮来调试

  • 至此编译和调试工作都可以正常进行了,如果 GDB 版本足够高,在调试 STL 程序时也会有很好的效果

  • 第一种方案的配置到这里基本结束了,大家可以继续探索这种方案,不过这种方案比较受制于 VS Code ,可移植性不高。接下来我们提出另一种方式来提高 VS Code 的 C/C++ 工程的灵活性。

方案二:VS Code 配合 Makefile 来提高 C/C++ 工程的可移植性

准备工作

  • 在方案一的基础上仍需准备如下内容:
  • 准备一套 Makefile 模板,比如说 https://github.com/TheNetAdmin/Makefile-Templates ,或者也可以自行写一套模板,一个好的 Makefile 模板可以省去很多麻烦
  • 安装编译工具与 make 工具:尤其是在 Windows 下,使用 make 是一个比较麻烦的事情,推荐大家使用 msys 提供的一套工具,这里有一个打包供下载 https://pan.baidu.com/s/1kV5hx3p

方案说明

  • 这个方案的思路是:使用 Makefile 来构建工程, VS Code 通过 Tasks 调用 make 工具来编译,再通过调用 gdb 来调试
  • 其优点在于不是过分依赖 VS Code 自身的配置,一个合适的 Makefile 可以在各个平台上执行编译,但是在开发过程中又可以用到 VS Code 自身的插件带来的便利,减少命令输入,减少命令行 gdb 调试带来的烦恼

步骤说明

  • 首先构建一个 Makefile ,如果没有合适的可以到这里找到一些现成模板
# originating https://github.com/TheNetAdmin/Makefile-Templates
# tool marcros
CC := g++
CCFLAG := -std=c++14
DBGFLAG := -g
CCOBJFLAG := $(CCFLAG) -c

path marcros

BIN_PATH := bin

OBJ_PATH := obj

SRC_PATH := src

DBG_PATH := debug

compile marcros

TARGET_NAME := main

ifeq ($(OS),Windows_NT)

TARGET_NAME := $(addsuffix .exe,$(TARGET_NAME))

endif

TARGET := $(BIN_PATH)/$(TARGET_NAME)

TARGET_DEBUG := $(DBG_PATH)/$(TARGET_NAME)

MAIN_SRC := src/main.cpp

src files & obj files

SRC := $(foreach x, $(SRC_PATH), $(wildcard $(addprefix $(x)/,.c)))

OBJ := $(addprefix $(OBJ_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC)))))

OBJ_DEBUG := $(addprefix $(DBG_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC)))))

clean files list

DISTCLEAN_LIST := $(OBJ)

$(OBJ_DEBUG)

CLEAN_LIST := $(TARGET)

$(TARGET_DEBUG)

$(DISTCLEAN_LIST)

default rule

default: all

non-phony targets

$(TARGET): $(OBJ)

$(CC) $(CCFLAG) -o $@ $? $(OBJ_PATH)/%.o: $(SRC_PATH)/%.c*

$(CC) $(CCOBJFLAG) -o $@ $< $(DBG_PATH)/%.o: $(SRC_PATH)/%.c*

$(CC) $(CCOBJFLAG) $(DBGFLAG) -o $@ $< $(TARGET_DEBUG): $(OBJ_DEBUG)

$(CC) $(CCFLAG) $(DBGFLAG) $? -o $@

phony rules

.PHONY: all

all: $(TARGET) .PHONY: debug

debug: $(TARGET_DEBUG) .PHONY: clean

clean:

@echo CLEAN $(CLEAN_LIST)

@rm -f $(CLEAN_LIST) .PHONY: distclean

distclean:

@echo CLEAN $(CLEAN_LIST)

@rm -f $(DISTCLEAN_LIST)
  • 根据这个 Makefile,构建一个目录结构如下的工程目录
- Project
- Makefile
- src: 所有源文件 (不得放在子目录)
- add.cpp
- add.h
- sub.cpp
- sub.h
- main.cpp
- obj
- 空
- debug
- 空
- bin
- 空
  • 然后对于 VS Code 的 tasks.json 和 launch.json 做一些修改如下
  • tasks.json
{
"version": "2.0.0",
"tasks": [
{
"taskName": "build",
"command": "make",
"args": ["default"],
"type": "shell"
},
{
"taskName": "build-debug",
"command": "make",
"args": ["debug"],
"type": "shell"
},
{
"taskName": "clean",
"command": "make",
"args": ["clean"],
"type": "shell"
}
]
}
  • launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
// 修改为新的测试目标文件路径
"program": "${workspaceRoot}/debug/main.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build-debug"
}
]
}
  • 之后就如方案一中的步骤使用编译和调试工具即可

  • 这样的话将这个工程迁移到其他平台也不用担心没有 VS Code 而无法使用
  • 同时,如果工程发生重构,那么只需要更改 Makefile 与工程结构即可,不需要在 VS Code 中修改过多

总结

  • 总体而言,经过微软官方团队一段时间的努力, VS Code 上的 C/C++ 开发体验有了很大提升,在面对一个比较小型的工程时,我们可以免去开启 IDE 的时间以及处理 IDE 目录结构的时间,从而快速打开工程,快速开发并验证思路

  • 但是 VS Code 毕竟只是一个代码编辑器,无论我们赋予它多少功能,其对大型工程的处理能力终究是不如 IDE 的。比如 Refactor ,包管理,动态类型纠错,语法纠错等功能一直是 IDE 的强项,所以在面对比较复杂的工程时,不用多想,还是乖乖使用 IDE 吧

        </div>

VS Code 配置 C/C++ 环境的更多相关文章

  1. Windows 10 Mac 为Vs Code配置C/C++环境

    2019-06-10 更新: 加上Mac版本的Vscode配置文件 0.前言 实现效果:右键一键编译运行C/C++文件 Vs code的代码效果很好看,也很轻量,所以想为Vs Code配置C/C++环 ...

  2. Visual Studio Code配置 HTML 开发环境

    Visual Studio Code配置 HTML 开发环境 https://v.qq.com/x/page/l0532svf47c.html?spm=a2h0k.11417342.searchres ...

  3. Visual Studio Code配置GoLang开发环境

    Visual Studio Code配置GoLang开发环境 在Visual Studio Code配置GoLang开发环境 作者:chszs,未经博主允许不得转载.经许可的转载需注明作者和博客主页: ...

  4. VS Code配置C/C++环境

    VS Code配置C/C++环境 一.下载和安装VS Code 1.访问VS Code官网下载安装包 2.安装VS Code 3. 安装后, 打开VS Code是英文,按住Ctrl+shift+x进入 ...

  5. Visual Studio Code 配置C/C++环境

    0. 前言 VS Code 是微软发布一款跨平台的源代码编辑器,其拥有强大的功能和丰富的扩展,使之能适合编写许多语言. 本文面向初学者(但不是纯小白),分享一点我配置C/C++的经验. 本文所有内容均 ...

  6. 1 visual studio code 配置C++开发环境 (windows 开发环境)

    0 引言 最近帮GF(不幸变成ex了)配置C++开发环境,一开始想给她装个visual studio13完事,但是一想到自己安装以及使用时的诸多麻烦,就有点退却,觉得没有这个必要.正好了解到vscod ...

  7. Windows VS Code 配置 Java 开发环境

    Windows VS Code 配置 C/C++ 开发环境 准备 Windows [这个相信大家都有 笑: )] VS Code JDK 建议 JDK8以上(不包含JDK8,关于 Windows环境下 ...

  8. Vs code配置Go语言环境-Mac

    背景:最近受朋友介绍,学习Go语言.那么开始吧,首先从配置环境开始. 电脑:Mac Air,Vs code已经安装 一.Go下载和安装 下载地址:https://golang.google.cn/dl ...

  9. VS Code 配置 C/C++ 环境(转)

      写作原因 微软的 VSCode 一直以来为人诟病的一个问题就是对于 C/C++ 工程的编译以及调试支持度有限,配置起来比较复杂,但是 vscode-cpptools 团队经过一段时间的 bug 修 ...

随机推荐

  1. OOP 1.2 const关键字

    1.2 const关键字 1.常量 指针常量 定义常量:const 类型 =值 定义指针常量:const *类型=值 常量指针不可通过常量指针修改其指向的内容 可直接修改其指向的内容 常量指针的指向可 ...

  2. struts2--文件上传大小

    Struts2文件上传的大小限制问题 问题:上传大文件报错-- 解决:修改struts.xml文件中的参数如下 <constant name="struts.multipart.max ...

  3. HttpCookie Class

    提供创建和操作各 HTTP Cookie 的类型安全方法. #region 写入指定Cookie的值 +static void WriteCookie(string cookieName, strin ...

  4. alpha6/10

    队名:Boy Next Door 燃尽图 晗(组长) 今日完成 学习了css的一些基本操作. 明日工作 抽空把javascript的基本操作学习一下 还剩下哪些任务 微信API还有京东钱包的API. ...

  5. MVC与MVP简单对比

    在Java平台,基于Spring等技术的MVC框架已经走向成熟:在.NET平台,微软也推出了MVC.MVP Framework,MVP不同于MVC的地方,关键在于,View不再显示的依赖于Busine ...

  6. mvc4中使用部分视图局部刷新实例

    如上效果图,网页中有主视图(上)和部分视图(下),点击提交会把文本框中的值发送到服务器,再返回所有添加的信息,在下方局部更新(只更新部分视图),实现如下: 1.网页主视图代码: @model MvcA ...

  7. UVA12585_Poker End Games

    题目是这样的,每个人手中有a和b的钱数,c为a和b中间最小的一个. 每个回合,两个人胜利的概率都是0.5,胜利者从失败者手中获得c的钱数. 如果有一个人手中没钱的话,那么他就failer,游戏结束. ...

  8. CSS预处理语言-less 的使用

    Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性,使 CSS 更易维护和扩展. Less 可以运行在 Node 或浏览器端. Less的编译处理 作为一 ...

  9. JS中数组和字符串具有的方法,以及substring,substr和slice的用法与区别

     String 对象属性 属性 描述 constructor 对创建该对象的函数的引用 length 字符串的长度 prototype 允许您向对象添加属性和方法 String 对象方法 方法 描述 ...

  10. 【EF】EntityFramework DBFirst的使用

    一.前言        久闻EF大名,之前做C/S产品用的是Dapper对SqlLite进行ORM.然后接触公司授权系统后发现用的是EntityFramework对SQLSever进行ORM.授权系统 ...