当前位置: 首页 > news >正文

【Linux】自动化构建-Make/Makefile

前言

        上文我们讲到了Linux中的编译器gcc/g++        【Linux】编译器gcc/g++及其库的详细介绍-CSDN博客

        本来我们将一个对于编译来说很重要的工具:make/makfile

1.背景

        在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile可以来定义那些文件先编译,那些文件后编译,那些文件需要重新编译。甚至是一些更为复制的功能

        makefile带来是好处就是"一键化编译",只需要一个make命令就可以实现。这极大的提高了开发的效率

会不会写makefile从侧面很大程度的反应了一个人是否具有完成大型工程项目的能力 

2.简单认识什么是make/makefile

make是一个命令工具,用于解释makefile中指令的工具

make是一个指令,makefile是一个文件,需要我们自己建立。两个搭配使用就可以实现我们的自动化编译

3.make/makefile的基本使用

3.1简单一键化编译

创建makefile,并使用vim写入内容(m大小写都可以)

hyc@hcss-ecs-4ce7:~$ touch makefile
hyc@hcss-ecs-4ce7:~$ vim makefile

makefile的基本结构为:依赖关系+依赖方法 

注:写入依赖方法前,要先点击TAB键。一定要TAB键不要4个空格,这是写书格式!!) 

退出并保存,执行make指令,自动化执行编译

hyc@hcss-ecs-4ce7:~$ make
gcc test.c -o testhyc@hcss-ecs-4ce7:~$ ./test
hi,Yuzurihahyc@hcss-ecs-4ce7:~$ ls
makefile  test  test.c

3.2简单一键化清理

再次打开makefile,写入清除命令

注:

        先忽略.PHONY:clear不看,clear的格式其实和上面的格式都是:依赖关系+依赖方法。只不过clear并没有依赖什么文件,就不写依赖文件

退出并保存,执行make clear,完成一键清除

hyc@hcss-ecs-4ce7:~$ ls
makefile  test  test.chyc@hcss-ecs-4ce7:~$ make clear
rm testhyc@hcss-ecs-4ce7:~$ ls
makefile  test.c

大家看到这里可能一头雾水,但是没关系我们来一个一个看

3.2.1为什么这个我们要使用make clear才能达到效果,而前面只需要执行make就可以了呢?

我们可以把这个两个指令交换一下位置,看看效果

我们可以看到此时我们执行make指令时,实现的效果就是清除效果 

hyc@hcss-ecs-4ce7:~$ ls
makefile  test  test.c
hyc@hcss-ecs-4ce7:~$ make
rm test
hyc@hcss-ecs-4ce7:~$ ls
makefile  test.c
总结: 

        执行make指令时,会从上到下扫描makefile文件,并且默认执行第一个扫描到的方法。如果想要执行其他方法,可以make + 目标名,显示的调用

3.2.2  .PHONY是什么东西?

.PHONY + 目标名用于声明伪目标

伪目标不是实际存在的目标,而是用于执行特定的命令(如清理)

.PHONT的主要功能是保证对应的依赖关系和依赖方法总是被执行 

要理解什么叫总是被执行?我们可以先理解什么叫不总是被执行。我们可以看到当我们多次执行make指令时,第一次正常执行,而后面的都不再执行了。这就叫不总是被执行。

而换做clear,则可以正常执行多次

同样的,当我们使用 .PHNOY修饰test时,也可以反复的执行编译语句 

 总结:

        .PHONY是定义伪目标,其功能是让其对应的依赖关系和依赖方法总是被执行但一般情况下编译都是不要.PHNOY修饰的,因为代码没有经过修改是不需要反复编译的。反复编译会极大的浪费资源。

补充:make是如何判断源文件是否被修改? 

1.文件的acm时间

make正是通过两个文件的Modify时间来判断出源文件是否被修改的。

如果可执行文件的时间晚于源文件时间,这代表没有被修改。反之,这代表源文件被修改了想要重新编译。

ACM时间小知识:

        Access时间并不是我们想象的我们访问一次就更新一次时间,因为整个系统最频繁的操作就是访问文件,如果每访问一次文件就统计一次时间这会带来巨大的开销。因此,Access时间是会等用户访问到一定次数才会更新

        Modify时间修改,Change时间往往也会一起修改。因为Modify是记录文件内容修改的时间,但是文件内容有修改其体积大小往往会修改,而体积是属于文件属性这一块的,所以Change时间也会修改。

4.make/makefile深入理解

4.1make的推导规则

现在makefile中为一下内容:

执行make指令我们可以看见,执行的指令顺序和我们写入makefile中的顺序是不一样的

因为makefile的推导规则是满足类似栈结构的:myproc由myproc.o文件推导,而myproc.o当先并不存在,要由myproc.s文件推导。那就先把推导myproc的指令入栈,先推导myproc.o文件。以此类推,直到前置条件完成后,通过出栈依次执行后面的指令

4.2makefile的升级之路

4.2.1makefile可以使用变量

makefile可以像我们的编程语言一样使用自定义变量,来指代文件、指令、选项等等

$:表示这个变量所指代的内容,比如:$(BIN)就表示myproc这个文件

4.2.2makefile中的特殊变量

$@:表示目标文件,既$(BIN)

$^:表示依赖文件,既$(SRC)

特殊符号可以帮助我们简化makefile的书写

4.2.3makefile中一段依赖关系中可以存在多个依赖方法

一段依赖关系中可以存在多个依赖方法,比如这里我们想直观的看到我们做了什么操作,就可以利用echo来输出信息

效果如下: 

我们这里看到了我们自己写是echo指令回显了,我们如果想要指令不回显只看效果,可以使用@符号

这样指令就不会回显了

4.2.4makefile处理多文件编译

对于多文件的编译,我们上一篇文章讲到过,我们一般都是先将所有文件编译为.o文件,最后在将所有的.o文件连接

%是makefile下的通配符%.c:%.o表示将当前路径下的所有.o/.c文件全部展开,比如有100个.c文件,这里就会展开一百个依赖关系,并执行一百个依赖方法。 

效果如下:

4.2.5makefile最终版本        

        上面我们说到,如果有多文件的编译makefile的处理方式。确实在依赖方法的书写上,这个便捷多了。但是我们没有考虑到这一切都是建立在使用变量上的,而我们的变量则需要将多个文件表示出来。

如果我们想要编译多个文件,就需要在变量里写多个文件 

 

 3个文件还能接受,可对于项目工程来说有上百个文件怎么办?我们不可能一个一个写上去

解决这一问题有两个方法

方法一:

  OBJ=$(SRC:.c=.o) :语法格式,将.c文件替换为同名.o文件
  SRC=$(shell ls *.c):使用命令行指令,一键获取.c文件

方法二:

 SRC=$(wildcard *.c) :wildcard为makefile的函数,其作用就是获取所有.c文件

至此这就是makefile的最终形态

相关文章:

  • 模拟搭建私网访问外网、外网访问服务器服务的实践操作
  • 详细讲解Flutter GetX的使用
  • 联通专线赋能,亿林网络裸金属服务器:中小企业 IT 架构升级优选方案
  • Linux 进程调度与管理:从内核管理到调度机制的深度解析
  • kafka命令
  • Linux:理解库制作与原理
  • 卡西欧模拟器:Windows端功能强大的计算器
  • day027-Shell自动化编程-基础
  • 如何安全高效的文件管理?文件管理方法
  • 109页PPT华为流程模块L1-L4级梳理及研发采购服务资产5级建模
  • 网页前端开发(基础进阶3--Vue)
  • 华为ICT和AI智能应用
  • 区域徘徊检测算法AI智能分析网关V4助力公共场所/工厂等多场景安全升级
  • 华为云Flexus+DeepSeek征文|华为云Flexus服务器dify平台通过自然语言转sql并执行实现电商数据分析
  • Vue前端篇——Vue 3的watch深度解析
  • 2025年想冲网安方向,该考华为安全HCIE还是CISSP?
  • SAP学习笔记 - 开发22 - 前端Fiori开发 数据绑定(Jason),Data Types(数据类型)
  • 华为手机开机卡在Huawei界面不动怎么办?
  • Vue3中Ant-design-vue的使用-附完整代码
  • 【C++】string类的模拟实现(详解)
  • 网站建设网站定制/seo建站
  • 网站怎样制作图文排版/百度官网
  • 如何部署asp网站/黑科技引流推广神器免费
  • 怎么做网站关键词库排名/专门的网页制作工具有
  • 做挂网站吗/谷歌关键词推广怎么做
  • 国内响应式网站/找一个免费域名的网站