vscode多文件编译问题

问题:

最近复习数据结构,需要码些代码,vscode在编译多文件时,还是出了些问题,编译单个c是没问题,为什么会这样呢??vscode如何组织多个c文件呢???当然这是本篇最终要解决的问题。但首先还得把自己没搞明白的事,搞清楚。单个文件编译器配置三个文件都是以*.json结尾,那就从json开始。

json文件在vscode作用?

  • json的数据结构??
    json是一种数据格式,是xml简化格式,现在被python脚本广泛使用。结构上,将所有数据(data)最终可解释为三种类型:

第一种类型是标量scalar,也就是一个单独的字符串string或数字numbers,比如“济南”这个单独的词。
第二种类型是序列sequence,也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组array,或者列表list,比如“山东,山西”。
第三种类型是映射mapping,也就是一个名/值name/value,即数据有一个名称,还有一个与之相对应的值,这又称作散列hash或字典dictionary,比如“省会:济南”。

  • json文件组织规则??
    规则是很简单的,只有四条。
    • 并列数据之间用逗号分隔
    • 映射用冒号表示
    • 并列数据集合(数组)用方括号表示
    • 映射的集合(对象)用大括号表示
  • 在vscode中的作用??
    在vscode中广泛的应用在配置文件中。具体到项目就是.vscode文件夹下的三个文件:
  • tasks.json(build instructions):主要作用就是构建说明文档
  • launch.json(debugger settings):调试器设置
  • settings.json:本工作区的设置,user文件下,对应settings.json是全局设置
  • c_cpp_properties.json编译器路径和 IntelliSense 设置

如何编译多个.c文件呢?

从编译原理知道:c程序是编译完了之后形成的是.O文件,即目标代码文件,然后由链接器Link来把他们链接在一起,也就是常说的compile只是产生.O文件,而build才是把这些.O文件连接起来形成一个可执行的程序。而编译器同一时间只会处理一个.c文件,所以vscode安装好插件后,并没有自动通过头文件链接项目引用的.c文件。这个就要告诉编译器需要链接哪些文件了。普遍的解决方案就是编写makefile文件。
安装 MinGW时已经安装了make的编译器:mingw32-make.

  • 什么是makefile???
    这个其实并不陌生,在学linux那段时间已经了解到有这个东西,就是引导编译程序具体编译哪些文件的。

  • make工程管理的作用???
    make,本意就是工程管理或叫构建管理工具,通过读入makefile来执行大量的编译任务。通过make命令控制源码的编译。make命令就是cmd下或powershell下执行 mingw32-make,后面可以跟参数,常用的有

    • -k:作用是在让make命令在发现错误时仍然就执行,而不是在检测到第一个错误时就停止,所以可是使用这个选项在一次操作中发现所有未编译成功的源文件
    • -n:作用是让make命令输出将要执行的操作步骤,而不是真正执行这些操作
    • -f:作用是告诉make将文件名为filename作为makefile文件。如果未使用这个选项,标准版的make命令将优先在当前命令下查找名称为makefile的文件,如果不存在名称makefile的文件,则开始查找名为Makefile的文件。
  • makefile文件的编写规则与原理???

   target : <prerequistus>
	[tab] <commands>

target(目标):这个不可省,链接的文件可以file也可以执行文件
prerequistus(前置条件):实现target,所需要的文件,可省
commands(命令):target满足依赖后执行的命令,可省;另外commands前要有一个tab空格。
原理:这就是makefile规则中最核心的内容,“满足依赖条件后,执行编译”。make就是依靠一层套一层的依赖,执行编译命令,最终实现可执行文件的。

到这里基本上,就可以理解如何编译多个.c文件了,问题是如何写一个可以执行的makefile文件呢,前面所说的commands都有哪些呢???详见扩展:

扩展:如何写makefile文件

  1. makefile文件里都有些什么呢??

a.显式规则
显式规则明确规定要生成的文件,文件的依赖文件,生成的命令。
b.隐晦规则
由于我们的makefile具有自动推导功能,所以就有很多隐晦的规则,有make自动推导出来的,不需要明确写出来
什么是make的自动推导呢??
make看到一个.o文件,它会自动把对应名字的.c文件加到依赖中,比如如果要编译一个what.o文件,其依赖为w.h和what.c文件,则只需指定w.h文件为依赖即可,因为what.c文件会自动加到依赖中。what.o : w.h
c.变量的定义
在makefile中我们要定义一系列变量,变量一般都是字符串,有点像c语言中的宏,当makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
d.文件指示
包括三部分,一个是在makefile中引用另一个makefile,就像c语言的include,另一个是根据某些情况指定makefile的有效部分,就像c语言的预编译#if一样,还有就是定义一个多行的命令
e.注释
makefile中用#来标明注释。并且只有单行注释,而当输入字符#时需要转义加反斜杠,即“#”

  1. commands包含的命令有哪些呢???
    规则中的命令和操作系统的shell的命令是一致的。每条命令的开头必须以tab键开头,除非命令是紧跟在依赖规则后面的分号后的。

  2. makefile的文件名??
    用Makefile就可以了。大多数make都支持makefile和Makefile.要指定其他文件名的文件作为makefile需要执行命令-f,如make -f Make.linux

  3. 引用其他makefile文件???
    跟c #include很像。include <filename>其中可以包含路径和通配符。-include <filename> 前面加了-号,表示无论include过程中出现什么错误,都不要报错继续执行。和其它版本make兼容的相关命令是sinclude,其作用和这一个是一样的。

  4. 文件查找实现??
    makefile只有一个目标,其他目标都是被这个目标所带出来的,所以第一条的目标也就是makefile要完成最终目标。所以不可避免的就会用到一类文件,所以就用到了通配符,make支持三种通配符:* ? … 如下列语句:

clean :
  rm -f *.c #把所有扩展名为c的文件都删除

用在变量中,则不太一样。*.c不再是所有的.c文件了,而就是它本身,想要表示所有的.c需要用到make的关键字:wildcard,如:
objects := $(wildcard *.o)
另一种文件查找的方法是使用特殊变量:“VPATH”。如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。格式为:
VPATH=src:../include #make会先找当前目录,找不到再找src目录,最后找 ../include;注意,两个目录间用:分隔开
还有一种是使用关键字 vpath,这种更灵活,有三种使用格式:

vpath <pattern> <directories> #<pattern>:指的是匹配的方法,%.h所有以.h结尾的文件,%表示匹配零个或若干个字符 <directories>:指定在哪个目录下查找,很好理解
vpath <pattern> #清除匹配方法的搜索目录
vpath #清除所有设置的搜索目录
  1. 清除编译目标???
    由于有大量的中间编译文件的存在,所以最后需要清除中间的文件。需要用到“伪目标”标记:.PHONY。格式如下:
     .PHONY: clean #不管有没有clean这个文件,都要运行下面的目标,使用 make clean来执行
    clean:
            rm *.o temp
#伪目标也可以被当作依赖,如下面的代码
    .PHONY: cleanall cleanobj cleandiff

    cleanall : cleanobj cleandiff #伪目标被当成依赖
            rm program

    cleanobj :
            rm *.o

    cleandiff :
            rm *.diff

东西确实有些多,目前掌握的就可以简单写个了。如遇到的顺序表依赖,体验一下:

阶段体验:编写简单makefile文件

SeqListTest:SeqListTest.o seq_list.o
	gcc SeqListTest.o seq_list.o -o main
SeqListTest.o:seq_list.c
	gcc -c SeqListTest.c
seq_list.o:seq_list.c
	gcc -c seq_list.c
.PHONY:clean

#linux 下用 rm -rf *.o main
clean:
	@echo "=======clean project========="
	del  *.o
	@echo "=======clean completed========="

将此文体放到项目目录下,在vscode TERMINAL下,输入mingw32-make,即可以完成编译。输入./main可以运行。输入mingw32-make clean可清除产生的中间文件,如下图所示:
在这里插入图片描述

总结

 至此,基本可以实现文件的编译了,但缺点是没法单步调试,至少对数据结构测试程序来说,够用了。
想要单步调试,有种比较弱智的办法,在构建说明文档中也就是task.json中-g -o之间加入要测试的.c文件,如下图所示:在这里插入图片描述

同时,编写makefile文件还有许多东西要看,文档真的是不能太长。先到这里,接下来,makefile编写还要继续学习详见:makefile深入之编写规则.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值