目录
1、什么是makefile
首先makefile是一个文件,makefile中保存了构建文件所需要的信息。然而仅仅只有这些信息是不足以自动构建一个项目的,它还要配套make命令使用。在外部make命令会根据makefile的文件内容进行解析,编译项目。
2、makefile的文件格式
目标对象:依赖对象
编译命令
生成makefile文件后执行make命令就可以看到程序已经编译好了
3、make的工作方式
3.1、make默认在当前路径下寻找文件名称为“makefile”或者”Makefile“的文件来进行解析,如果找不到,则报错。
3.2、只为生成一个目标对象而服务,如果生成了目标对象,则后续的文件当中的内容不解析。
我们现在来验证一下:我们可以看到当前文件夹下面有两个源文件text.c 和text.c还有一个Makefile文件。
[1] 我们将编译text.c 和编译text1.c的命令都写在Makefile文件当中。
[2] 接下来执行我们的make。我们可以发现只执行了gcc text.c -o mytext,只生成了mytext而并没有生成mytext1。
3.3、如果为了生成第一个目标对象,则需要先生成依赖对象,则在makefile文件中查找生成依赖对象的方法。 如果发现依赖的对象不存在,再报错返回。
[1] 我们来验证一下:当前文件夹中只有Makefile和text.c。
[2] 接下来打开我们的Makefile文件将依赖文件改为text.o。
[3] 执行make命令我们发现也执行成功了,而在makefile文件中也并没有找到生成依赖对象的方法,那与我们上面所说的:“如果为了生成第一个目标对象,则需要先生成依赖对象,则在makefile文件中查找生成依赖对象的方法。 如果发现依赖的对象不存在,再报错返回。”并不相符,这是因为make在找不到生成依赖对象的方法时会给我们酌情生成,也就是说这里的text.o是make在没有找到依赖对象和生成依赖对象的方法时酌情给我们生成的。
当然我们肯定也不能依赖make去帮我们生成,而我们要自己踏踏实实的写。
[4] 我们将mytest删除,text.o删除。将text.c 改为mytext.c在执行make我们可以发现这次直接报错了,make并没有酌情帮我们生成text.o这是因为make并没有在我们当前的目录下找到一个名为text的源文件。
我们接下来看看正确的做法:
[1] 当前目录下只有mytext.c并没有text.o。
[2] 但在生成mytest时需要依赖text.o那么,我们就要在makefile中找到给到生成text.o的方法。
[3] 接下来我们执行make命令,可以看到先生成了text.o文件,然后又依赖text.o生成了可执行程序mytest。
3.3、若依赖对象的最后一次修改时间前于目标对象的最后一次修改时间,则不生成
[1] 首先我们要理解这句话先来看下面的张图我们构建的场景,可以看到依赖对象最后一次修改的时间(6号的晚上22:39)是前于目标对象的修改时间(7号的早上09:07)的。
[2] 接下来我们执行发现命令行提示符说:make:mytest is up to date (mytest是最新的)
总结: 也就是说我们可以这样理解这句话,就是生成可执行程序依赖的源代码如果不修改,那么执行make命令就不会再生成新的可执行程序。
4、内置变量:
4.1、$^:所有依赖的对象
4.2、$@:目标对象
[1] 我们可以用$^代替依赖对象,用$@代替目标对象
[2] 我们看到可以正常使用make命令
[3] 这里的$^为什么要说是代表所有的依赖对象呢,我们可以看以下的一个场景
[4] 在这个场景中我们创建了许多的空源文件,然后进行编译,我们发现依旧可以编译成功并运行。所以说那些空源文件并不会影响我们的编译。也就是说一个目标文件可以有多个依赖文件。
[5] 同理我们可以在makefile中写入所有可依赖文件。
4.3、$<:代表第一个依赖对象
4.4、自定义变量
[1] 可以自己给变量起名字,后续使用$符号进行解析(这里的$符号功能就相当于解引用符号)
[2] 可以看到输入make命令时依然将my_o替换为-o命令
5、伪目标
[1] makefile中定义伪目标方式:
.PHONY:[伪目标名称]
伪目标:[依赖对象]
命令
[2] 我们在makefile中写好伪目标的代码后执行make可以发现伪目标无论在什么情况下都会帮你去执行命令(不管你依赖文件的修改时间是否前于目标文件都会去帮你实现)
[3] 我们还可以定义无依赖对象的伪目标
[4] 配合make+[伪目标名字]来执行命令
[5] 可以配合make命令中间用“;”隔开同时执行两条命令。
看官看到这里可不可点一个免费的赞👍这对我真的很重要!!!