Linux系统编程02

makefile的原理

问题需求

之前我们讲过C语言代码主要是经过编译和链接两个步骤生成目标文件,但是在编译的时候我们可能需要进行多条指令的输入,要对main函数所在的文件进行汇编,再将我们定义的函数文件进行汇编,分别形成*.o文件,然后再使用gcc命令将两个汇编文件链接成目标文件,在这个过程中我们就需要手动敲三条指令,这样非常消耗人力,因此我们想到用脚本的方式,将这几条指令封装再一起,只要源文件发生改变就执行脚本,顺序执行这些编译指令,但是如果我们将指令顺序的写好,假如我们的源文件只有部分发生改变,一部分没发生改变,那没发生改变的那部分其实是不用进行编译的,但是我们如果只是将指令简单封装成顺序执行的脚本,那么就无法实现我们说的精准编译,会造成重复编译,从而增加编译所需时长,然而makefile就可以帮我们解决这个问题

makefile:增量编译生成代码

只有目标文件不存在或者目标比依赖旧才会执行命令

目标文件:生成的文件

依赖:生成此目标文件需要操作的文件
makefile的实现

(1)名字必须是 Makefile / makefile

(2)规则的集合【规则:一个目标文件,0 ~ 多个依赖文件,0 ~ 多个命令,每个命令之前要加一个tab键】

(3)把最终要生成的文件作为第一个规则的目标

makefile基本使用

(1)首先我们再文件里面创建两个原文件,并且再main文件里面调用了只在main里面进行声明但是定义再add.c里面的函数add

(2)我们再当前文件下创建一个名为Makefile的文件,并且再里面添加相对应的规则

按照规则要求将生成最终文件main的文件作为第一个规则,并且在:后面指定由哪些文件来执行指令得到目标文件

第二行先输入tab在输入要将main.o文件和add.o文件生成main文件的操作指令

下面就是相对应的文件以及相应的操作命令

执行make命令,编译器便会按照增量编译原理进行编译

假如我们编译之后文件我们都没有改变过也没有使用 touch指令区操作过文件,那么此时执行make指令就不满足增量编译原理,那么就不会进行编译

如果我们使用例如touch命令或其他修改文件的命令去操作文件,那么执行make就会按照增量编译原理对修改的文件进行重新编译

伪目标

(1)目标不存在

(2)执行了命令生成不了目标

如果每次make都一定要执行的指令我们就可以使用伪目标,因为我们在执行makefile指令时,我们首先会检测文件夹中是否存在我们所需要的目标文件,并且会检测目标文件的和其依赖的文件哪个更新,如果我们所需要的文件不存在,或者依赖文件比目标文件新,那么make就会执行相应的指令,因此伪指令就是在其执行指令之后,不会生成对应的目标文件,因此每次执行make都会满足调用伪目标执行的操作

clean指令清除main.o和add.o文件,每次执行make clean都会执行clean 因为文件中不存在clean文件,但如果文件中村内在clean文件,我们需要删除此文件才能执行此命令

执行make rebuild就会先执行clean,在执行main的相关指令

为了让开发者更好的找到Makefile里面的伪目标,我们通常用.PHONY:来指定伪目标

增加makefile的通用性

我们发现假如我们源文件名更改,其他依赖的文件名发生改变,或者我们想要另一组文件名不同但是编译结构类似的代码使用makefile这时我们的选择就是重新创建makefile文件,但是这也会给我们造成很大的工作量,因此我们想到可以用变量的形式,和函数一样,用变量代替里面具体执行的逻辑,然而变量的改变并不会影响程序运行逻辑,因此我们考虑到用变量代替文件名,以此来提高代码的通用性

变量也分为:

(1)自定义变量 变量名:=值 (所有值都是字符串类型) 引用变量用$(变量名)

(2)预定义变量

此时我们发现其编译出来使用的命令全是cc,不是gcc,因此我们需要将cc替换掉

(3)自动变量 同一个变量名 值随着规则变化而变化

在上面修改的Makefile文件中,我们可以发现当我们当我们拷贝Makefile文件到其他程序中时,我们还需要改3行的数据,分别时2,6,8行的数据,这样其实也会给我们带来一定的工作量,因此我们在次发现下面两次指令都是相同的,并且他们的目标文件名都是死第一个命令的依赖文件名,因此我们可以用%来通配main和add,可以修改为一下这样的情况

但是这还不够,这样子还需要我们对Makefile文件进行修改,我们想让Makefile文件直接可以不用修改;这就需要依靠wildcard通配符,其作用时从当前目录的所有文件中,取出符合要求的文件名,这样我们就可以取出当前目录下的所有*.c的文件,但是我们需要的不是*.c的文件,我们需要的时*.o的文件,这就需要我们用patsubst---pattern substitude对我们的文件名进行文字替换

这样就可以让Makefile文件自动读取依赖文件,自动生成,而无需修改文件内部的内容

正常执行命令

扩充:假如我们在一个文件夹下,由多个main函数,我们想用Makefile进行编译,需要各个.c问价生成自己的可执行文件,这个时候该i如何书写

相关推荐
宴之敖者、几秒前
Linux——\r,\n和缓冲区
linux·运维·服务器
LuDvei1 分钟前
LINUX错误提示函数
linux·运维·服务器
未来可期LJ8 分钟前
【Linux 系统】进程间的通信方式
linux·服务器
Abona9 分钟前
C语言嵌入式全栈Demo
linux·c语言·面试
心理之旅19 分钟前
高校文献检索系统
运维·服务器·容器
Lenyiin23 分钟前
Linux 基础IO
java·linux·服务器
The Chosen One98528 分钟前
【Linux】深入理解Linux进程(一):PCB结构、Fork创建与状态切换详解
linux·运维·服务器
大佐不会说日语~1 小时前
使用Docker Compose 部署时网络冲突问题排查与解决
运维·网络·spring boot·docker·容器
Kira Skyler1 小时前
eBPF debugfs中的追踪点format实现原理
linux
No0d1es1 小时前
电子学会青少年软件编程(C语言)等级考试试卷(三级)2025年12月
c语言·c++·青少年编程·电子学会·三级