1.Makefile中的主要内容
一个Makefile文件主要包括以下五部分内容:
- 1.显示规则:显示规则一般用来描述一个目标文件如何被生成,包括要生成的目标,该目标依赖的文件,生成该文件的命令语句。在Makefile中命令应当以一个tab键开始。
- 2.隐晦规则:前面说过make具有自动推导功能,这就是Makefile的一种隐晦规则,即make默认的一种规则,这些规则即使没有被显示地写出来也会被make去自动执行。
- 3.变量定义:前面说过,Makefile中的变量定义与C语言的中的宏定义类似,变量本质是字符串,当Makefile被执行时,定义的变量都会被变量所代表的内容替换。
- 4.文件指示:这部分内容前面并没有提到过,但是简单来说就跟C语言中一个源文件中包含头文件一样,一个Makefile也可以包含另一个Makefile中的内容,被包含的文件会原封不动地放在当前文件的包含位置。
- 5.注释:Makefile中只有行注释,使用"#“符号来代表该行的内容为注释。如果要使用”#",则可以加一个"/"进行转义。
2.关于Makefile的文件名
当执行make命令的时候,make会默认在当前目录下按顺序去寻找文件名为"GNUmakefile",“makefile”,"Makefile"的文件,找到了就解释执行这个文件,一般默认使用"Makefile"这个文件名。
当然也可以用别的文件名来写Makefile,比如Makefile.test。想要执行指定文件名的Makefile,执行make命令的时候需要用-f + 文件名的方式显示的指示Makefile文件名,如:
make -f Makefile.test
执行过程如下:
merlin@Ubuntu1804:~/learn_makefile$ mv Makefile Make.test
merlin@Ubuntu1804:~/learn_makefile$ make -f Make.test
gcc -c -o main.o main.c
gcc -c -o add.o add.c
gcc -c -o multiply.o multiply.c
gcc -o main main.o add.o multiply.o
3.包含其他Makefile的内容
在Makefile中使用include<filename>的方法将其他Makefile文件中的内容包含进来,被包含的文件会原封不动地放在当前文件的包含位置。
例如两个Maedile文件:
Makefile.param:
CC = gcc
OBJS = main.o add.o multiply.o
Makefile:
include Makefile.param
main:$(OBJS)
$(CC) -o main $(OBJS)
main.o:main.c add.h multiply.h
add.o:add.c add.h
multiply.o:multiply.c multiply.h
clean:
rm main
rm *.o
就等于:
Makefile:
CC = gcc
OBJS = main.o add.o multiply.o
main:$(OBJS)
$(CC) -o main $(OBJS)
main.o:main.c add.h multiply.h
add.o:add.c add.h
multiply.o:multiply.c multiply.h
clean:
rm main
rm *.o
对于有包含其他Makefile文件的Makefile文件来说,当make来解释这个文件的时候,对于没有指定路径的文件,make会首先在当前目录下寻找include所指出的其他Makefile,并把其内容在当前位置展开。**对于不同包含文件中的同名变量,前面的会被后面的覆盖掉。**如果没有找到该文件,若make执行时带有"-I"(–include-dir)参数,那么make就会到该参数指定的目录中去寻找文件。
4.Makefile中通配符的使用
顾名思义,通配符就是通配的意思。在Linux系统中,如果我们要删除很多个相同后缀名的文件,比如.txt文件,我想你不会一个个地使用rm+文件名的方式来删除这些文件,而是如下一条命令便可以完成对所以.txt文件的删除:
rm *.txt
这里的*便是一个通配符。
make也支持三种通配符,分别是"*","?“以及”[…]",通配符代替了一系列文件。make的通配符除了使用在命令中,也可以使用在变量中。
5.make工作方式总结
make执行的一般步骤如下:
- 1.读入所有的Makefile
- 2.读入被include的其他Makefile文件
- 3.初始化文件中的变量
- 4.推导隐晦规则,并分析所有规则,包括显示规则
- 5.为所有目标文件创建依赖关系链
- 6.根据依赖关系决定哪些目标需要被重新生成
- 执行生成命令生成最终目标文件
Makefile书写规则包括两个部分,一个是依赖关系,一个是生成目标的方法。Makefile中生成的目标文件可能有很多个,但是只应该有一个最终目标,所以应该把最终目标写在第一条规则的位置。如果在第一条规则中写了多个目标,那么这些目标中的第一个会被认为是最终目标。
一般来说,make会以UNIX标准的shell,也就是/bin/sh来执行Makefile中的命令。