windows上使用VsCode开发C/C++

时间:2024-06-20 16:07:56

使用VsCode+makefile开发C/C++

1. 介绍

  vscode作为现在越来越受欢迎的编辑器之一,因为可以使用插件让vscode支持几乎市面上所有的编程语言,由于笔者主要接触的是 C/C++ 方面,因此在这里简单介绍一下如何搭建vscode编译、调试C/C++项目的过程;整套环境完全使用开源软件进行搭建,只需要做很少的改变就可以无缝搬移到linux中;采用的方案是:vscode+git+mingw gcc+makefile;最后有详细的技术说明和资源分享(GitHub 项目:vscode_c_demo);

  介绍一下笔者搭建的平台和所需要的软件:

windows上使用VsCode开发C/C++    windows上使用VsCode开发C/C++    windows上使用VsCode开发C/C++    windows上使用VsCode开发C/C++    windows上使用VsCode开发C/C++    windows上使用VsCode开发C/C++

1. win7 以上;

2. VS Code 官方下载地址

3. Git (官方下载地址);

4. mingw GUN 编译工具 (官方下载地址);

5. 在VS Code中你需要安装

5.1. C/C++ 插件(用于智能代码提示);

5.2. Chinese (Simplified) Language Pack(中文简体支持包,英文好的请忽略)

下载安装VsCode插件比较简单;点击右侧图标搜索即可;windows上使用VsCode开发C/C++ ,或者 快捷键 "Ctrl+Shift+X",搜索上述插件名称即可;

笔者不建议在mingw 的官网下载GCC 编译器;因为网络的速度会很慢,会等很久;很多开源的编译器都会自带mingwGcc编译器;例如DEVC++ 、Qt 等;

这里提供一个百度链接 https://pan.baidu.com/s/1x-jXHtiiWI0Kc1l34M_LrA       提取码:8q0d  ;里面有上述所需要的所有安装包;截至2019年11月8日,里面的安装包均是最新版本,里面请区分32bit和64bit;

 2.安装软件

上述所有软件下载好之后,我们就可以开始安装程序了,所有程序可以一起安装,这里我们只讲解安装过程中的注意事项;

首先安装中,安装路径中不能出现中文;尽量避免空格 !

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

2.1  mingw GUN GCC 编译器

mingw 在我的百度云链接中是压缩包,我们把他解压到指定位置后(我解压的位置是C:/mingw32 ),将编译器的bin目录添加到系统环境变量;如何添加系统环境变量请自行百度;

查看是否添加成功:打开 cmd(window + R 输入cmd打开命令行窗口) 输入   g++ --version   如果出现类似以下字样表示设置环境变量成功;

windows上使用VsCode开发C/C++

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

2.2  Git

git 的默认编辑器是 vim 如果你从来没有听说过Git,那么请一路 next 安装;如果你有听过git ;我想我这个菜鸟也帮不了你啥~;如果你正在学习git,你可以看看这篇文章:git学习笔记--基础运用

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

2.3  VS Code

安装vscode 也比较简单,只有一个需要注意

windows上使用VsCode开发C/C++

一定要将 “通过Code 打开操作” 添加到目录的上下文菜单,后期作用会比较大;其他选项请自行选择;

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

 2.4  安装插件

windows上使用VsCode开发C/C++                       windows上使用VsCode开发C/C++

插件安装之后会提示重启vscode 激活插件,重启即可

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

3.配置参数

 1. 导入一个示例项目

这边你们可以随便导入一个项目,可以有多个文件夹,文件夹中可以有.c/.h文件,但是有一个要求,就是在里面的文件不存在冲突;即文件夹里面的源文件都是需要用到的,就算没有用到,也没有命名冲突等系列问题;

因为接下来的这个makefile会自动将你项目文件夹下所有的.c/.h文件全部编译,如果出现冲突,那么请你自己解决;最好的情况是:你用到了哪些文件你就放入哪些文件,不需要的文件可以修改他的后缀名;

为了方便展示,我从github 上clone 一个项目到文件夹下;在文件夹空白处右键单击,选择git bash here 输入:

git clone https://github.com/KimAlittleStar/vscode_c_demo.git

克隆成功后,右键点击生成出来的 vscode_c_demo文件夹;open with vscode ;文件树如下:

windows上使用VsCode开发C/C++

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

2.设置默认的shell 命令行

点击左下角 齿轮图标 选择 设置 或者  点击 文件->首选项->设置 打开如下界面

如果你选择用户,那么更改的是默认配置,如果你选择工作区,那么你做的设置只会在这个文件夹内部起作用;

windows上使用VsCode开发C/C++

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

3.让VScode 提供智能提示

windows上使用VsCode开发C/C++

//C:/Git/bin/bash.exe 应该是你安装的git的bin目录下的bash.exe
//C:/mingw32/bin/gcc.exe 应该是你安装的mingw下bin目录的gcc.exe
//如果你的项目是C++ ,请换成 g++.exe
//如果复制此段单吗到你的 setting.json文件后出错,请删除注释
{
"terminal.integrated.automationShell.windows":"C:/Git/bin/bash.exe",
"C_Cpp.default.compilerPath": "C:/mingw32/bin/gcc.exe"
}

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

4.设置编译任务task.json 和 运行设置  launch.json

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
//此 json 文件中需要注意的就是 执行makefile的执行文件是 mingw32-make.exe ,如果你使用qmake 或者其他make 执行文件,替换它即可;其他不需要修改
"version": "2.0.0",
"tasks": [
{
"label": "build", //task的名字,调用方式就是 task build
"command": "mingw32-make.exe", //会在命令行中调用此命令
"args": [ //调用上述 mingw32-make.exe 传递给它的参数
"target=${workspaceRootFolderName}.exe" //${workspaceRootFolderName} 会被替换成 根目录 即:vscode_c_demo
],
"type": "shell",
"problemMatcher": []
}, //此命令等效展开为:mingw32-make.exe target=vscode_c_demo.exe
{
"label": "build-debug",
"command": "mingw32-make.exe",
"args": [
"target=${workspaceRootFolderName}.exe",
"DEBUG=-g", //添加debug 参数 使gcc 生成调试信息
"PREDEF=Debug" //相当于在程序中定义了一个宏定义 #define Debug
],
"type": "shell"
}, //此命令等效展开为:mingw32-make.exe target=vscode_c_demo.exe DEBUG=-g PREDEF=Debug
{
"label": "clean",
"command": "mingw32-make.exe",
"args": [
"clean",
"target=${workspaceRootFolderName}.exe"
],
"type": "shell",
"problemMatcher": []
}, //此命令等效展开为:mingw32-make.exe clean target=vscode_c_demo.exe
{
"label": "runing",
"command": "./runExcute.sh",
"args": [
"${workspaceRootFolderName}.exe" // 传给脚本的参数
],
"type": "shell"
} //此命令等效展开为:mingw32-make.exe target=vscode_c_demo.exe 然后执行 ./vscode_c_demo.exe
]
}

task.json

{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
//
//这里我们需要注意修改的是:"miDebuggerPath": "C:/Qt/Tools/mingw730_64/bin/gdb.exe"
//
//这里gdb的路径应该是你自己的gdb 文件路径
//
// "program": "${workspaceFolder}/${workspaceRootFolderName}.exe"
// 这里调用的exe 应就是 task build-debug 中生成的可执行文件;
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动", //名字,会显示在debug 的选项中
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/${workspaceRootFolderName}.exe", //表示要调试的可执行文件在当前打开的文件下下的这个文件,此名称需要和task 中的target=<>,一一对应;
"args": [],
"stopAtEntry": false, //时候要在main函数处自动停止,false表示不会停止,true表示会在main函数处自动停止;
"cwd": "${workspaceFolder}", //表示首先要切换到当前目录下
"environment": [],
"externalConsole": true, //为true时,会新建一个黑窗口运行程序,如果为false ,就会在vscode中新建终端,
//不过这样就需要在用户设置中设置默认bash 为 gitbash,否则会报错
"MIMode": "gdb",
"miDebuggerPath": "C:/Qt/Tools/mingw730_64/bin/gdb.exe", // 这里填写的应该是你自己gdb.exe文件的路径;一般与g++.exe minwg32-make.exe 在同一文件夹下
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build-debug" //在执行这个gdb launcher 之前,首先执行task build-debug;
}
]
}

launch.json

windows上使用VsCode开发C/C++

贴一下task.josn 和 launch.json 的代码

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

5.尝试运行

快捷键  CTRL + P 打开命令行 输入 task+空格+任务命令 即可执行相应命令

task.json中一共创建了4个命令; 分别是  build build-debug clean running

task build #创建一个文件夹名字相同的可执行文件;并且所有的中间文件都会生成放在build文件夹下;

task build-debug #与build类似,但是会生成调试信息,如果你想使用gdb等工具调试,那么必须使用此选项;

task clean #清除所有由build带来的文件

task runing #一共分两步,首先build ,其次调用其可执行文件;

task命令解释

windows上使用VsCode开发C/C++

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

 6 DEBUG 选项

vscode Debug使用的是mingw32中的gdb.exe调试,与平常的断点调试并无太大差异;

具体使用方法如下:点击左侧导航键 虫子的图标,选择(gdb)启动,点击右方绿色的开始图标,vscode会自动开始编译,运行到断点处会自动停止,更多设置请参考上文launch.json中的注释

windows上使用VsCode开发C/C++

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

4.原理分析

整个环境搭建最主要的工作在于:mingw32-make.exe 中,实际上,如果你安装了git ,并按照上述方式修改了默认的终端为 gitbash,那么你只需要在终端中输入 mingw32-make.exe target=a.exe ,也会自动生成一个a.exe的可执行文件,在终端输入mingw32-make.exe clean target=a.exe,也可以清除所有由build带来的所有新建的中间依赖文件;task.json的作用就在于 当我 输入 task build 时 ,就相当于我在gitbash中输入了mingw32-make.exe target=DirName.exe 这个命令;

  接下来我们会分析为什么mingw32-make.exe 可以做到这些,如果你仔细观察我们的文件树,你会发现文件树中有一个没有后缀的文件叫 makefile,我们可以打开makefile 文件,

#此项目源文件后缀类型
PROJECTTYPE = .c #您想要生成可执行文件的名字 如果外部没有赋值,那么使用obj.out
target ?= obj.out #是否生成DEBUG选项
DEBUG ?= #系统之外的宏定义
PREDEF ?= #获取当前makefile绝对路径
pes_parent_dir:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))//// #删除路径下最后一个 /
pes_parent_dir:=$(subst /////,,$(pes_parent_dir)) #获得mkfile 的实际路径 测试使用, 没有实际用到 可删除
mkPath:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))////
mkPath:=$(subst /////,,$(mkPath)) #将所有宏定义前方加入-D指令以便给编译器识别
DEF := $(foreach n,$(PREDEF),-D$(n)) #获取目录下所有子目录
AllDirs := $(shell cd $(pes_parent_dir); ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') . #添加成为绝对路径
AllDirs := $(foreach n,$(AllDirs),$(subst .,$(pes_parent_dir),$(n))) #获取所有 .c/.cpp文件路径
Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*$(PROJECTTYPE))) #设置*.o 和 *.d 文件的存放路径
buildPath :=$(foreach n,$(Sources),$(subst $(pes_parent_dir),$(pes_parent_dir)/build,$(n))) #处理得到*.o 后缀文件名
OBJS := $(patsubst %$(PROJECTTYPE),%.o, $(buildPath)) #同理得到 *.d文件名
Deps := $(patsubst %$(PROJECTTYPE),%.d, $(buildPath)) #需要用到的第三方静态库
StaticLib := #需要用到的第三方动态链接库
DynamicLib := #真实二进制文件输出路径
Bin :=$(pes_parent_dir)/$(target) #C语言编译器
CC = gcc #C++编译器
CXX = g++ #简化rm -f
RM = rm -f #C语言配置参数
CFLAGS = -g -pedantic -std=c11 -Wall -o #C++配置参数
CXXFLAGS = -g -Wall -std=c11 #头文件搜索路径
INCLUDE_PATH = $(foreach n,$(AllDirs) , -I$(n))
LDFLAGS = #指定AllLibs为终极目标 即:最新的Bin
AllLibs:$(Bin) #声明这个标签 des 用于观察当前的路径是否正确
.PHONY:des
des:
@echo OBJS = $(OBJS)
@echo cur_makefile_path = $(pes_parent_dir)
@echo AllDirs = $(AllDirs)
@echo Sources = $(Sources)
@echo Deps = $(Deps)
@echo makefilePath =$(mkPath)
@echo bulidPath=$(buildPath)
@echo PREDEF = $(DEF)
@echo DEBUG = $(DEBUG) #对应关系 在本makefile中以空格隔开的后缀为.c 都会为其生成一个新的.d文件
#$(pes_parent_dir)/build/%.d :$(pes_parent_dir)/%.c
# @echo 'finding $< depending head file'
# @if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;
# @$(CC) -MT"$(<:.c=.o) $@" -MM $(INCLUDE_PATH) $(CPPFLAGS) $< > $@ #对应关系 在本makefile中以空格隔开的后缀为.c 都会为其生成一个新的.d文件
$(pes_parent_dir)/build/%.d :$(pes_parent_dir)/%.c
@echo 'finding $< depending head file'
@if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;
@set -e; rm -f $@; \
$(CC) -MM $(INCLUDE_PATH) $(DEF) $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$ #对于include中的*.d文件,只要里面任意有一个文件被修改,那么就会触发此规则生成一个新的*.o文件
%.o: %.d
@echo compile $(patsubst %.d,%.c,$(subst build/,,$<))
@$(CC) -c $(patsubst %.d,%.c,$(subst build/,,$<)) $(DEBUG) $(DEF) $(INCLUDE_PATH) $(CFLAGS) $@ $(Bin) : $(OBJS)
@echo bulding....
@$(CC) $(OBJS) $(CFLAGS) $(Bin)
@echo created file: $(target) .PHONY : clean
clean:
@echo '清理所有文件ing...'
@$(RM) -r $(pes_parent_dir)/build/
@echo '清理可执行文件ing...'
@$(RM) $(Bin)
@echo 'done' .PHONY : cleanO
cleanO:
@echo '清理Obj && Dep'
@$(RM) -r $(pes_parent_dir)/build
@echo 'done'
#main.out: $(OBJ)
# cc -o main.out $(OBJ) include $(buildPath:.c=.d)

makefile

  在上述makefile 中,比较关键的语句在于

#获取目录下所有子目录
AllDirs := $(shell cd $(pes_parent_dir); ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') .
···
#对应关系 在本makefile中以空格隔开的后缀为.c 都会为其生成一个新的.d文件
$(pes_parent_dir)/build/%.d :$(pes_parent_dir)/%.c
@echo 'finding $< depending head file'
@if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;
@set -e; rm -f $@; \
$(CC) -MM $(INCLUDE_PATH) $(DEF) $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$

shell cd  $(pes_parent_dir) 表示切换路径到该makefile 的目录下,然后 ls -R :递归输入该目录下的所有文件以及文件夹;如果是文件夹,那么就会单独起一行然后文件夹名字前有 ‘.’ 作为标记 后面的grep 和 awk 、gsup 都是linux下才有的命令;

同理在 下方 if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi; 所做的逻辑就是判断当前想要生成的*.d文件的目标文件夹在不在, 不在则创建它, 其中 dir  mkdir 都是linux中才会有的命令,当然windows下也有与其差不多功能的命令,但是此makefile我希望在linux下也能用,这个时候怎么办呢,这个时候就要介绍我们的 Git 了,git在windows中使用的命令行软件 bash.exe 就把上面的命令都覆盖到了,也就是说,如果我们使用windows 自带的cmd.exe 或者 powerShell.exe 里面都会使得 dir mkdir 和其他命令找不到,导致makefile错误终止;所以我们才需要安装Git ,所以我们才需要将Git bash 设置成为vsCode 默认的终端;因为只有git bash 中才可以调用上述makefile中的几个shell命令

还记的我们将mingw32编译器的路径加入到了系统环境变量里面去了~为什么呢?

#C语言编译器
CC = gcc #C++编译器
CXX = g++

因为 在makefile 的编译器中,gcc 、g++ 只是简单的字符,只有将gcc 、g++ 的路径加入了环境变量,他们才能正确的被找到;

还有,如果我们想管理C++ 项目这个时候怎么办呢~我们只需要在 makefile中将所有的 $(CC) 替换成 $(CXX)  所有 的$(CFLAG) 替换成 $(CXXFLAG) 就可以了哦~

makefile中其他的只是我就不赘述了,你可以参考这个链接:一个自动管理项目的makefile

最后献上我整个项目的github地址https://github.com/KimAlittleStar/vscode_c_demo

里面有所有的项目文件,以及配置文件,和较为详细的注释;只需要修改几个简单的路径就可以完成上述的配置;我都有在json文件里面说明哦~~~

---------------------------------------------------------------------------------------华丽丽分割线---------------------------------------------------------------------------------------

如果关注度还可以的话;

我会选择更新:

一键/自动转换 C/C++ 项目的makefile,

编写一个只清楚中间文件,而不清除可执行文件的task

搭建VSCode + 嵌入式 ARM编译调试环境

码字不易,觉得稍微有点用的,可以在git里面 star一下,博客点个小赞;

读书的时候就想了2、3年的事情,现在终于快要看到成功了;