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如何书写

相关推荐
蜡笔小马4 小时前
15.Boost.Geometry 坐标系统详解
c++·boost
网云工程师手记4 小时前
DDNS-Go部署与使用体验:动态公网IP远程访问不再断
运维·服务器·网络·网络协议·网络安全
AD钙奶-lalala5 小时前
Android编译C++代码步骤详解
android·开发语言·c++
HalvmånEver5 小时前
Linux:基于信号量的环形队列与生产者消费者模型(一)
linux·运维·服务器·信号量
rhett. li5 小时前
FreeBSD系统中使用clang/clang++编译Skia源码的方法
c++·ui·用户界面
海兰5 小时前
手把手elasticsearch学习增删改查之“增”
运维·jenkins
_风华ts6 小时前
C++函数指针
c++·函数指针
威桑6 小时前
解决 Qt6 程序 在Linux 环境下无法输入中文的问题
linux·c++·qt
浅念-6 小时前
C++ :类和对象(4)
c语言·开发语言·c++·经验分享·笔记·学习·算法
shentuyu木木木(森)6 小时前
栈与队列基础
c++··队列