vscode多文件编译问题
发布日期:2021-07-16 18:25:47 浏览次数:3 分类:技术文章

本文共 4297 字,大约阅读时间需要 14 分钟。

vscode编译c项目多文件编译问题

问题:

最近复习数据结构,需要码些代码,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 : 
[tab]

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 
#
:指的是匹配的方法,%.h所有以.h结尾的文件,%表示匹配零个或若干个字符
:指定在哪个目录下查找,很好理解vpath
#清除匹配方法的搜索目录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 mainSeqListTest.o:seq_list.c	gcc -c SeqListTest.cseq_list.o:seq_list.c	gcc -c seq_list.c.PHONY:clean#linux 下用 rm -rf *.o mainclean:	@echo "=======clean project========="	del  *.o	@echo "=======clean completed========="

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

在这里插入图片描述

总结

 至此,基本可以实现文件的编译了,但缺点是没法单步调试,至少对数据结构测试程序来说,够用了。

想要单步调试,有种比较弱智的办法,在构建说明文档中也就是task.json中-g -o之间加入要测试的.c文件,如下图所示:在这里插入图片描述

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

转载地址:https://blog.csdn.net/guangod/article/details/118157173 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:软件工程复习之软件生命周期
下一篇:软件工程复习之软件测试

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年03月11日 15时11分25秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

android开发的取消清空按钮,Android开发实现带清空按钮的EditText示例 2019-04-21
android gp服务,ArcGIS Runtime SDK for Android开发之调用GP服务(异步调用) 2019-04-21
mysql整体会滚_滚mysql 2019-04-21
向mysql数据库中添加批量数据类型_使用JDBC在MySQL数据库中快速批量插入数据 2019-04-21
最全的mysql 5.7.13_最全的mysql 5.7.13 安装配置方法图文教程(linux) 强烈推荐! 2019-04-21
mssql连接mysql数据库文件_在本地 怎么远程连接MSSQL数据库 2019-04-21
mssql 远程无法连接mysql_解决SQLServer远程连接失败的问题 2019-04-21
linux mysql c++编程_Linux下进行MYSQL的C++编程起步手记 2019-04-21
Maria数据库怎么复制到mysql_MySQL、MariaDB数据库的AB复制配置过程 2019-04-21
mysql5.6 icp mrr bak_【mysql】关于ICP、MRR、BKA等特性 2019-04-21
mysql utf8跟utf8mb4_MySQL utf8 和 utf8mb4 的区别 2019-04-21
docker mysql开机自启动_Docker学习4-学会如何让容器开机自启服务【坑】 2019-04-21
在mysql中删除表正确的是什么_在MySQL中删除表的操作教程 2019-04-21
mysql有3个共同好友_共同好友mysql 2019-04-21
代理查询 mysql_查询数据库代理设置 2019-04-21
mysql dif_mysqldiff实现MySQL数据表比较 2019-04-21
mysql 允许其他主机访问权限_允许其他主机访问本机MySQL 2019-04-21
druid不能close mysql连接_alibaba druid mysql连接问题 2019-04-21
mysql 设置按天分表_MySQL 优化实战记录 2019-04-21
java连接mysql 不推荐_java连接mysql 2019-04-21