Linux中Makefile详细教程
目录
如果只执行make,它执行的是Makefile里哪一段语句呢?
Makefile
Makefile的介绍
make是一个命令
makefile/Makefile是一个文件.
1.什么是Makefile脚本?
Makefile脚本集合了程序的编译指令的文件,make是一个命令工具,当执行make命令时,它会自动读取Makefile中的编译指令并执行,会自动完成整个项目的自动化编译工作.
2.为什么需要Makefile脚本:
项目中如果有很多.c文件,它们的编译指令会有很多,需要的编译时间比较长,依赖关系非常复杂。
当项目中的.h文件被修改时,对应的.c文件需要重新编译,但是我们无法人为的分辨出哪些文件需要重新编译,只能全部重新编译一下,这项操作非常耗时。此时Makefile便发挥了用场.
所以make/Makefile又叫自动化的构建项目.
Makefile简单的编写
Makefile主要由两部分组成:a.依赖关系,b.依赖方法
我们举个例子:
你在学校,然后给你爸打电话,电话通了之后你说: "爸,我是你儿子",然后就直接挂了.
这样你就表明了依赖关系,我们是父子关系,但是后面什么都没有说了,你爸爸以为你遇到了什么危险.
这个时候你又打过去了说:“孩子没钱了,打点生活费吧",此时这个便才是依赖方法.
所以我们Makefile要达成一个目的,必须要满足这两个条件.
我们举个实际代码的例子来理解:
我们直接
vim Makefile
此时便会创建一个Makefile文件并且打开.
假设此时有一个test.c源文件,我们想编译成mytest可以执行文件.
依赖关系:
mytest:test.c
其中mytest称作目标文件,test.c称作依赖文件.
依赖方法:
必须第依赖关系的下一行,以Tab键为空开始写.
编译源文件,需要用到gcc,之前所讲过的.
gcc test.c -o mytest
这样一个简单的Makefile文件便写好了.
从vim中退出来,编写一个简单的test.c文件:
此时目录下会有两个我们刚才创建的文件:Makefile和test.c
我们直接执行make命令:
我们发现执行命令之后,有了我们想要的mytest可执行文件,然后再./执行这个文件,发现程序成功运行了.
.PHONY
那如果我们想清理某个文件,该怎么写呢?既然是清理文件那还需要依赖什么文件删除吗?
这个时候需要用一个东西叫 .PHONY伪目标.
因为我们clean目的是清除某些文件,而删除操作又不会需要依赖文件,所以会创建一个伪目标,相当于依赖这个伪目标,然后执行依赖方法.
格式如下:
1.先在前面写一个.PHONY:clean
2.第二行紧接着输入clean:
3.Tab键开头,然后输入依赖方法 rm -rf mytest
所以输入进去应该是这样:
然后我们使用一下它。退出vim,执行make clean
我们发现mytest文件被删除了.
还有一个作用就是总是被执行.
什么叫总是被执行呢?先来看如果我们一直make会发生什么呢?
可以发现这里的意思是说mytest已经是最新了.但是我就是想让它每次都执行,这个时候你在前面加上.PHONY即可:
然后退出,便可以每次都被执行了.
这里有一个问题:
问题:
如果只执行make,它执行的是Makefile里哪一段语句呢?
默认是执行第一个依赖关系和依赖方法.
我们第一个写的是gcc编译的,第二个才是clean,所以我们直接执行make是将test.c源文件编译成mytest可执行文件.
为了验证,我们可以交换一下两个的顺序:
退出vim, 此时我们执行make,发现执行的语句成为了rm
想要编译,需要自己手动输入:make mytest.
此时便编译完成,生成了一个可执行文件.
还是紧接着上面的,它是
怎么知道我的可执行程序是最新的呢?
根据文件的最近修改时间!
这里有一条命令stat,它可以查看一个文件的重要的三个时间!
Access:最近的访问时间.
Modify: 最近的内容修改时间,比如你修改了文件的内容,这个时间就会改变.
Change:最近的属性修改时间,比如你修改了这个文件的读写权限,这样它的属性修改时间就会被修改.
我们知道一个文件是由内容+属性组成.如果内容被修改,那么文件的大小也会被修改,相应的属性修改时间也会改变,所以这点也要注意.
那是如何判断的呢?可执行文件形成的时间一定要晚于源文件。这点是大家可以理解的,因为可执行文件是由源文件编译生成的.
所以只需要比较两者的时间,只要可执行文件的时间一直比源文件晚(新),就说明这个可执行文件一直是最新的.
我们如果修改源文件,此时源文件的时间就一定会比可执行文件新,这个时候再次可以执行gc
c便可以编译了.
如果有多个文件,我们该如何使用Makefile编写呢?
Makefile编译多个文件
首先创建一个test.h文件,用于声明:
再将test.c文件里内容做修改如下:
再创建一个main.c用于执行.
在编写Makefile时,我们习惯于把依赖文件写成.o的形式.而.o又需要.c来编译。所以Makefile会自动向下寻找这些编译语句,我们只要写上编译的语句即可.
执行make语句.
发现已经编译成功且正常输出.
这就是编译多个文件的方法了.
进度条小程序
vim pro.c,进入pro.c,然后输入代码:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#define NUM 102
int main()
{
char bar[NUM];
memset(bar,0,sizeof(bar));
int cnt = 0;
const char* lable = "|/-\";
while(cnt <= 100)
{
printf("[%-100s][%d%] %cr",bar,cnt,lable[cnt%4]);
bar[cnt++]='#';
fflush(stdout);
usleep(30000);
}
printf("n");
}
vim Makefile,在Makefile下输入:
pro:pro.c
gcc -o pro pro.c
.PHONY:clean
clean:
rm -rf pro
然后退出vim,输入make,执行编译命令
最后./pro即可.
Makefile相关的内容便结束了.