写作原因

  • 微软的 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. Live Archive 训练题

    7091 Height Ordering Mrs. Chambers always has her class line up in height order (shortest at the fro ...

  2. QT中文乱码解决方法

    由于我毕设的界面是用Qt做的,之前没怎么接触过Qt,所以实现过程中遇到不少小问题,头一个就是这个. 现如今宝宝将其记录下来,供同样有需要的同学或者自己以后方便查阅. 1.所有文件编码格式须一致 不统一 ...

  3. HTTP vs HTTPS

    参考博文:HTTP与HTTPS的区别 HTTP与HTTPS的区别 一.HTTP和HTTPS的基本概念和区别 HTTP: 是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(T ...

  4. centos 6 编译emacs-24.5

    yum install `yum deplist emacs | grep provider | awk -F: '{print $2}' | awk '{print $1}' | xargs` yu ...

  5. 简述Java中Http/Https请求监听方法

    一.工欲善其事必先利其器 做Web开发的人总免不了与Http/Https请求打交道,很多时候我们都希望能够直观的的看到我们发送的请求参数和服务器返回的响应信息,这个时候就需要借助于某些工具啦.本文将采 ...

  6. JS高级 2

    递归:函数自己调用自己 在JavaScript中唯一能产生作用域的东西是 函数!js中只有函数可以创建作用域 词法作用域,也叫做静态作用域 //就是在代码写好的那一刻,变量和函数的作用域就已经确定了, ...

  7. linux的一些机制Signal, Fork,

    signal(SIGCHLD, SignalHandler); 注册软中断,对应的api close(socket); ret=fork(): 父进程,返回子进程的pid. 子进程返回0, 出错返回& ...

  8. java 数据结构与算法 之查找法

    一.二分查找法 二分查找就是将查找的键和子数组的中间键作比较,如果被查找的键小于中间键,就在左子数组继续查找:如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素. @Test public ...

  9. C#非泛型集合类与泛型集合类的区别 (转)

    来自:http://blog.csdn.net/jiayanhui2877/article/details/7623845 C# 泛型集合之非泛型集合类与泛型集合类的对应: ArrayList对应Li ...

  10. webpack打包css样式出错

    有两个组件home和search 两个组件中都有class为footer的元素 但是search的footer比home的多一条background的样式 本地开发的时候没问题,但是打包之后,home ...