目录
一、make和Makefile的本质
我们用window系统上的编译器,例如vs2019进行代码编译时,我们可以创建项目,进行多个.c文件的链接编译,那么,我们如何在Linux系统上利用gcc编译器实现该功能呢?如果对项目的部分文件进行了修改,可以只重新编译被修改的文件吗?
答案是肯定的。make和Makefile可以解决这些问题。
Makefile是一个为了实现自动化编译而存在的文件,它需要描述整个工程的编译链接规则及其先后顺序,围绕依赖关系和依赖方法进行编写。而且在Makefile 中可以使用系统shell所提供的任何命令来完成想要的工作,编写成功后可以通过make指令直接运行编译项目相关的代码。
make是一个命令工具,它解释Makefile 中的指令。
二、Makefile的规则
target... : prerequisites ...
command
...
...
---------------------------------------------------------------------------------------------------------------------------------目标(garget):程序产生的文件,如可执行文件和目标文件等;也可以是要执行的动作,如 clean,也称伪目标。
依赖(prerequisites ):用来产生目标的输入文件列表,一个目标可以依赖于一个或多个文件, 伪目标没有依赖文件。
命令(command):make执行的命令(shell命令或可在shell下执行的程序)。注意:每个命令 行的起始字符必须为Tab字符。
如果依赖文件中有一个或多个文件更新的话,对应的指令就要执行;make指令执行前会做检查,如果目标文件生成的时间是在最新更新时间之后的话,对应的指令就不会执行。这就是Makefile最核心的内容。
举例说明:
其中,依赖关系的查找是从上到下进行的,若当前依赖关系对应的依赖文件存在,则停止查找,开始从下往上执行命令(依赖方法)。故该实例中,依赖文件的查找顺序:test.o——>test.s——>test.i——>test.c 。其逻辑先后顺序类似于栈,“先进后出”。
三、.PHONY的功能
下面用两个文件进行说明。
Makefile1
Makefile2
上面的两个文件均是Makefile文件,均可以与make命令搭配使用来实现程序的自动编译,两个文件的内容大同小异,唯一的区别在于Makefile1中的伪目标clean 用.PHONY修饰了,而Makefile2中没有。
从上面的操作看,无法区分出有无.PHONY给Makefile为文件带来的不同。
如何区分? 在当前目录创建与伪目标同名的文件clean。
综上可得,.PHONY可以屏蔽与当前项目文件同目录下的与伪目标同名的文件带来的干扰,即可以使得伪目标对应得指令总是被执行 ,而不受与伪目标同名的文件的干扰。
四、make和Makefile的功能
Makefile文件描述了整个工程的编译、链接等规则。通过Makefile文件,make工具完成并自动维护编译工作。可以利用make工具可以进行程序的自动编译。包括:
1.如果仅仅修改了某几个源文件,则只重新编译这几个源文件;
2.如果某个头文件被修改,则重新编译所有包含该头文件的源文件。
因此,make和Makefile的结合使用在自动编译的同时,还可以减免不必要的重复编译。
五、实例
创建目录example并编写文件add.h mul.h add.c mul.c main.c,利用Makefile文件描述整个工程的编译、连接规则。使用make工具实现自动化编译。
六、总结
make和Makefile是一对用来实现自动化编译的工具,是在Linux系统编写和运行工程代码的关键。本文简要介绍了make和Makefile的一般编写格式和Makefile的规则。对于一般的编程需求,掌握这些就可以解决,但是关于make和Makefile,我们需要学习的还有很多,后续有必要的时候会进行进一步的学习。