|
01 前言 $ D6 K, p4 T$ ~" b7 j
有位朋友让我推荐一款Win10下好用的C语言编辑器,我毫不犹豫的选择了VSCode。免费、小而快、插件多这三点是我选择它的理由,本文就详解VsCode下编译、配置、调试C代码。(长文和多图预警!!可以收藏需要安装和配置时参考) 02 环境准备
5 X$ r2 L. n9 D c8 v编译器,VSCode只是个编辑器,C语言编译器要另外下载安装,笔者使用的MinGW64,安装好后一定不要忘记配置好环境变量,可以使用gcc -v确认编译器是否配置好。
VScode 官网下载安装。 03 编译运行
& ^, u7 F# Y$ _命令行编译运行 新建C文件,熟悉的HelloWorld。
这个时候可以使用命令行运行,VSCode菜单栏Terminal--->new Termial 如下进入目录直接运行。
一键运行 打开VSCode 安装下面俩个插件
安装好后选中c文件点击VSCode右上放的三角或者使用Ctrl+Alt+N即可运行。运行结果如下
多文件编译运行 上面讲述的都是单个文件的时候运行,从上面了解到其实Code Runner只是代替你手动输命令,当你需要少量的多文件运行,可以更改settings.json的gcc命令来实现。以如下目录结构为例,VSCode打开工作目录,
Ctrl+Shift+P 搜索settings 打开JSON文件
把settings.json 修改如下:
& u9 G, v) j& }3 C- {
& O4 Y; I6 Q3 u, S - "files.autoGuessEncoding": true,
; l: y7 G6 c3 I) `8 E - "code-runner.runInTerminal": true,
. t' K* z) X: [) w - "files.associations": {},
" ]0 R/ B7 n' y9 |/ e8 u/ ` - "code-runner.executorMap": {* g L' a8 y" I% k* d2 L# ]
- "c":"cd $dir && gcc *.c ../../hello2/src/*.c ../../hello1/src/*.c -I ../inc/ -I ../../hello2/inc/ -I ../../hello1/inc/ -o $fileNameWithoutExt && $dir$fileNameWithoutExt",( g0 i$ _( R# ?& P2 K1 t, z" v$ R
- },
0 ]* o9 F. ^! b' @2 x! [: g - }
复制代码 # B- q+ n, \/ S1 A% h- m; S
其实就是按照gcc 源文件1.c 源文件2.c -I incPath1 -I incPath2的命令修改即可,注意头文件的路径可以是相对路径也可以是绝对路径,如果#include的时候把头文件的路径加上,gcc 编译的时候可以不用把路径加上。当程序文件很多架构大时,需要学习makefile的编写,使用make命令。还是以上面的文件为例。 Makefile文件
, g: t: e" g% v- MainExt =.exe
8 i- H' [6 d( y8 }. }- U; Y - SourceExt =.c: t. w: S3 j1 e" \9 r W% `
- TargetExt =.o
; k& x9 E6 ], B' d5 J, u7 x - ( N" }, P, I1 W$ J: B/ f! \: [
- OBJ_DIR := obj
( G' r% U' J: e. u5 V+ L4 S9 Y - BIN_DIR := bin
G( l8 x u. Y2 Q. b - MAIN_SRC_DIR := main/src
( Q2 m: i& m a# t8 Z - MAIN_INC_DIR := main/inc% G# ]# k+ f& P# }
- HELLO1_SRC_DIR := hello1/src. R! \6 q' J8 k! Q, x+ |
- HELLO1_INC_DIR := hello1/inc
3 \& [. V4 Z9 @- C4 Q - HELLO2_SRC_DIR := hello2/src9 T$ x a$ _8 {9 P
- HELLO2_INC_DIR := hello2/inc
# |3 _, R2 B* v, q - 8 A6 M/ D7 d( m- T6 T+ n4 P1 }
- cc := gcc+ L: F% k; ^9 r0 Z$ ?
- CFLAGS := -g -Wall -I./$(MAIN_INC_DIR) -I./$(HELLO1_INC_DIR) -I./$(HELLO2_INC_DIR) -DDEBUG G. }( ?, d4 p/ R7 b3 O
7 t( G; C- w! i; E- MAIN_SRCS := $(wildcard $(MAIN_SRC_DIR)/*.c); D5 G9 ^# h# V9 h
- MAIN_HDRS := $(wildcard $(MAIN_INC_DIR)/*.h); f& p% X+ s, g8 q3 o. ^
- HELLO1_SRCS := $(wildcard $(HELLO1_SRC_DIR)/*.c): J6 K3 L/ x5 w, R% u) `1 p4 s
- HELLO1_HDRS := $(wildcard $(HELLO1_INC_DIR)/*.h)7 M4 s- e, ^. H" B8 K5 K6 m' T$ w
- HELLO2_SRCS := $(wildcard $(HELLO2_SRC_DIR)/*.c)! ~1 U0 `5 C$ O7 G5 F& D& ]
- HELLO2_HDRS := $(wildcard $(HELLO2_INC_DIR)/*.h)
9 \: z% B' D- R- q! @1 k - OBJS := $(patsubst $(MAIN_SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(MAIN_SRCS))
' q* b8 Q0 ? W0 @ - OBJS += $(patsubst $(HELLO1_SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(HELLO1_SRCS))
9 W1 b, a- |0 ]/ D* ^- j - OBJS += $(patsubst $(HELLO2_SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(HELLO2_SRCS))
* G) X( H: Q9 }4 \" W+ v# x7 G
! z$ w; \( t" l. p9 h- TARGET := $(BIN_DIR)/main$(MainExt)
) p, Y3 d/ W* B1 U" ?3 B# S
2 ]( S0 G6 m( {. G- .DEFAULT_GOAL := $(TARGET)
! \: `8 A7 |0 @/ Y- b/ U4 [
( o. K% g/ M% r5 k/ {; a- $(TARGET): $(OBJS)8 k6 A+ R2 f" c% Y+ h: R3 ?
- $(cc) $(CFLAGS) -o $@ $^$ U- v( J- U6 m# @2 A$ w
* j. L0 {7 W! }: P- $(OBJ_DIR)/%.o: $(MAIN_SRC_DIR)/%.c: V" u0 _6 s, Y3 a' S
- $(cc) $(CFLAGS) -c -o $@ lt;. o& `4 \: r- i+ p$ ~# A( e( H v
5 h+ Q# a! e( ~8 U- $(OBJ_DIR)/%.o: $(HELLO1_SRC_DIR)/%.c/ F J l. X" C: N
- $(cc) $(CFLAGS) -c -o $@ lt;6 k8 T% Y: ]3 o% x$ g8 q
# H$ [7 v" c7 U( ]' {- $(OBJ_DIR)/%.o: $(HELLO2_SRC_DIR)/%.c
- V9 }# j3 Z! A1 X; t - $(cc) $(CFLAGS) -c -o $@ lt;3 }) E- ^2 n }/ i
- + i2 _ ^8 u& y* D8 s& d l
- .PHONY: clean
: C* e% Y/ a# j# X: ^ - clean:, U/ N0 V4 e5 z4 C6 m
- del .\$(BIN_DIR)\*.exe
# n4 J3 f6 f) {( l8 W4 m - del .\$(OBJ_DIR)\*.o
复制代码
; v m- J9 J& F- X- g: V把settings.json 修改如下: - ( m5 I* t( H4 O( I8 G
- {: v1 r& r3 w( q/ q
- "files.autoGuessEncoding": true,# G% D8 d) ]* p3 u' {
- "code-runner.runInTerminal": true,
( O Q& K) A$ s1 R H) j9 T7 f - "files.associations": {},/ H' o- ?% x3 a9 Q8 H% j. z
- "code-runner.executorMap": {
6 Z# s+ l- u( H8 _2 J - "c":"make && ./bin/main.exe",; M2 r4 _/ S6 B. R
- },# o. F0 l4 s( u# ~3 P
- }
复制代码 - Q% w: [; r7 x+ b$ S- l
运行结果
注意:win10下make命令要和编译器安装路径下的make可执行文件一致,我是把安装路径D:\Program Files\mingw64\bin\minGW64-make.exe修改为make.exe,不修改要使用minGW64-make命令 04 调试
& m9 L: a% s/ ^6 A+ c* `( z我们经常要调试代码,下面来看看调试的配置。 A. F) q! ]# ~; R( A: ~/ Z! T
打开工作目录(调试的话工作路径不能含有中文) 在工作目录下新建文件.vscode并创建tasks.json 和launch.json,可以手动创建也可以Ctrl+Shift+P 弹出的对话框中搜索后根据引导创建。
创建完成后根据自己的需求修改内容,下面给出单文件和多文件的一个示例。 单个文件调试 launch.json 配置内容如下: - 3 n e" {7 c2 g/ `' A1 f: ], A
- {
( A5 ~. n' ]& o5 z+ K6 @+ g( q/ r+ r+ b - // Use IntelliSense to learn about possible attributes.- G& Y# w% V% u0 V
- // Hover to view descriptions of existing attributes.4 p+ r" j1 _; ]& D. k1 ^5 Y
- // For more information, visit: http://go.microsoft.com/fwlink/?linkid=830387" Q* s7 P8 ~0 z9 o8 V
- "version": "0.2.0",
) Q7 A' W3 a# J0 S; i - "configurations": [4 I- ~ h8 o- x, k9 ^
- {; j" O0 X8 j7 D1 R' Q0 v6 |
- "preLaunchTask": "Build", //调试会话开始前执行的任务,一般为编译程序。与tasks.json的label相对应
% b* F d! c) H/ Z! I# S - "name": "(gdb) Launch", //配置文件的名字,可以随便起
1 p( ^; g( c5 ]) f, l! X/ S - "type": "cppdbg", //调试的类型,Vscode现在支持很多,我这里主要是C,所以只能是cppdbg
9 f& y3 P4 i- Y/ ~2 b - "request": "launch",//配置文件的请求类型,有launch和attach两种,具体看官方文档
1 ~2 Q/ P" n4 N7 b" T, k8 a8 {9 T* b - "targetArchitecture": "x64", //硬件内核架构,为64bit,如图设置) M; b! {/ a) J' |1 F/ ^
- "program": "${workspaceFolder}/${fileBasenameNoExtension}.exe",//可执行文件的路径和文件名称
1 D) k" g( c- }, P0 h/ Q( z8 D - "args": ["file1", "file2"],//主函数调用时传入的参数
4 `) C8 _( i& I, e# ? - "stopAtEntry": true,//设为true时程序将暂停在程序入口处/ a2 e" ~/ O0 l( A8 ~1 r2 o$ j
- "cwd": "${workspaceFolder}",//调试时的工作目录
: K5 `4 u$ h, p2 D& F: n% G5 O - "environment": [],
# d# @& L& @' f8 }* L - "internalConsoleOptions": "openOnSessionStart",//false8 u. d) F T4 l7 K
- "externalConsole": false,//调试时是否显示控制台窗口3 v5 A5 Q5 n1 W- u+ g# |! @
- "MIMode": "gdb",//指定连接的调试器,可以省略不写6 Z/ ^8 h2 Z8 B
- "miDebuggerPath": "D:/Program Files/mingw64/bin/gdb.exe",//安装minGW具体路径 更据自己安装的目录修改( I w2 p" W; w$ S/ b$ I3 `
- "setupCommands": [
% F i$ ?/ p9 l - {8 L# W4 L0 v7 n# [: I! Y5 I
- "description": "Enable pretty-printing for gdb",
) T/ }( V' L, L2 W/ u - "text": "-enable-pretty-printing",
4 w) x* G2 R0 ]; q0 d+ g - "ignoreFailures": true. F# C. p. J+ L5 P( e2 V
- }
" h& C6 G) g$ u0 l3 D - ]8 n+ O/ z- L$ \8 I7 s0 J* X
- }
! t( W! J: p. u! \ - ]
# ^: J+ `$ R# O1 {, B - }
复制代码 , z/ _" Y- n- |% ~1 L
tasks.json 配置内容如下: - , R, D, P, P* H: D# d
- {
C8 b0 J4 J* S - // See http://go.microsoft.com/fwlink/?LinkId=733558, G$ `. g. o* t8 D# J
- // for the documentation about the tasks.json format5 h5 R0 b& r6 N
- "version": "2.0.0",
{" k) `6 v- [) Y - "tasks": [
6 ]' C. E6 C4 ?- V1 f% {' Y' Y2 f - {) S/ D' `4 H) h+ w( L0 s
- "label": "Build",# C; X8 s4 v( h4 R5 h- |4 R
- "type": "shell",
/ |6 F9 M* j% B6 [' j& w - "command": "gcc",: ?- B1 u6 c' ]+ E6 _
- "args": [" T$ Z1 V4 U8 }( s3 u& U, c
- "-g",$ V: h' B$ s% @- V: Y+ r4 Q, A
- "-o",0 R( Y1 ^1 a! F5 _9 c# `
- "${fileBasenameNoExtension}",
3 r3 l) Z' z A( E$ J! | Y - "${fileBasenameNoExtension}.c",
1 ?5 U3 r7 f* Z3 u' H( _+ ~0 L - ],9 y) G% M3 D8 Q9 o8 r6 O' B
- "group": {
* Z; x1 ~* {3 B3 N - "kind": "build",
+ m1 T+ o. s8 o, K& `' t' H - "isDefault": true
9 c# n6 y# ?# | - }
: i: M' W: p( K4 M* G: @ - } G+ n; B% Q6 V2 ]. y3 P& ^' o8 E
- ]# G% ^0 j$ J- `6 S
- }
复制代码
3 Q& j- H3 N8 N: k3 B6 J* K8 W. A4 I
配置完成后选择待调试的目标文件,按F5就可以调试代码。
多个文件调试 和上面配置CodeRuner的Settings.json一样当少量文件时我们可以简单的修改tasks.json中的gcc命令实现。以前文的目录结构为例修改后的tasks.json:
5 q4 A: O. J4 t- {
/ s2 i/ t$ Y- j9 L - "version": "2.0.0",. G) E+ V7 j% [! g% k& V' e' k0 g
- "tasks": [
. c# I% P# o' K+ }2 `6 w - {
; [ f8 [' i6 n) s: B0 d: g - "label": "Build",
w1 v& C8 l& d - "type": "shell",- c/ P# T8 c5 O j8 z; Z( c" @$ L
- "command": "gcc",
& u5 q+ D# V! M6 j* _2 j. @- O - "args": [6 ` B/ B+ f% d
- "-g",
" Z& S5 C& p" z - "-o",# l) g Q5 e" K+ W
- "${fileBasenameNoExtension}",. y- {9 f8 i/ R& |2 r
- "main/src/${fileBasenameNoExtension}.c",
/ T1 d. T B8 q5 O; G% m - "hello1/src/*.c",
" T/ O6 o4 t; T/ u, I - "hello2/src/*.c",
9 v+ q8 g i8 z& O* T* O5 u - "-I",/ D$ I# \% n6 Q" X
- "main/inc/",1 F/ \) J6 d# z0 }; X
- "-I",7 d, f) i1 d, u# G
- "hello1/inc/",
6 h9 ~9 F$ ]% T# o: h& N! N, I - "-I",
0 t" z$ A4 w1 n1 ^$ c - "hello2/inc/",6 r% y3 ^- Y3 x- `8 `& A- S& z8 G
- ],
' h' m; I$ L& ?4 u9 M$ _, c8 Y - "group": {
7 ?/ L+ \2 b- v# K6 d! B# c7 @ - "kind": "build",
L( F f5 z L$ }* F - "isDefault": true
0 b# _- `+ e, J7 b - }! t9 n" h. i) D' b( b1 d
- }# ^, W+ I+ q2 Q2 N
- ]
7 b: O# O7 n5 y! H, _; j - }
复制代码
7 N- c) [( H2 F3 F% k; d3 i) \当程序文件很多架构大时同样需要配合Makefile使用,仍使用前文的例子修改tasks.json中的command如下:
- s$ O% X, N8 r$ e; I4 I. M& s. F- {1 G% c8 D" j; `( E+ M5 w V! h ^
- // See http://go.microsoft.com/fwlink/?LinkId=733558! n5 y; |9 i9 D( R
- // for the documentation about the tasks.json format
2 z/ m: M$ z! \7 Q9 [, w# c - "version": "2.0.0",
2 a4 `; H3 ~( R- Q# N; l - "tasks": [) Q4 Y$ q& Q6 f% v/ c
- {7 S- p* Z* O Z+ D D W! r6 n' @
- "label": "Build",
5 W2 j; g4 Q' T, o, k - "type": "shell",8 S3 J6 h2 m8 J, P
- "command": "make",2 |# V, Q: P4 Q( Y2 R+ r
- }
9 s0 U! @: A, e/ n$ [) s7 w - ]
1 w# G) Q3 N$ r* o: D - }
复制代码
5 C7 C9 j/ c, {注意:launch.json文件中 "${workspaceFolder}/${fileBasenameNoExtension}.exe",//可执行文件的路径和文件名称要和Makefile生成的.exe路径一样。 ( N. I( ~, ~% M2 t1 I$ w4 z U
|