一、Makefile语法基本规则

目标(target)…:依赖(prerequiries)…
命令

备注:
目标(target): 通常指要生成文件的名称,可以是可执行文件或OBJ,
也可以是要执行动作的名称,比如clean
依赖(prerequiries):通常指要生成目标文件所需要的材料,可以有多个。
命令: 通常指生成目标时所需要执行的动作。

二、Makefile函数调用

1. 调用Makefile函数的语法格式:

$(functtion arguments)

这里"function"指要调用的功能函数,"arguments"指该函数的参数,参数

与函数用空格隔开,参数与参数用逗号隔开

2. 常用Makefile函数

(1)wildcard : 扩展通配符 例:src=$(wildcard *.c)从当前文件夹中找出所有.c赋给变量src

(2)notdir : 去除路径

(3)patsubst :替换通配符

(4)echo: 打印输出内容

(5)@echo: 打印输出内容但是不打印命令(echo)

(6)$@: 表示规则的目标文件名

(7)$^: 表示所有依赖的名字

(8)$<: 表示第一个依赖的文件名

三、Makefile静态模式

objects = foo.o bar.o

$(objects): %.o: %.c

上述语句的含义:
①要生成的文件是objects中所定义的文件名

②要生成的目标文件是objects中以.o结尾的文件名

③生成这些文件依赖于与这些.o文件同名的.c文件

四、Makefile中给变量赋值

1. = 是递归展开式变量

value1 = 5
      
	 value2 = $(value1)
      
     value1 = 6

最终$(value2)就变成了6

2. := 是直接展开式变量

value1 := 5

      value2 := $(value1)

      value1 :=6

最终$(value2)是5

五、Makefile实例分析

代码:

src := $(shell ls *.c)             #取当前文件夹下的所有.c
	
	objs:= $(patsubst %.c,%.o,$(src))  #将src中的.c文件名替换成后缀为.o文件名( 注意实际并没生成.o文件,
									    #如果Makefile中需要调用.o文件,必须通过gcc命令生成 )

	test: $(objs)                      #指明要生成目标test,必须依赖于objs所注明的.o文件(注意:上文虽
	                                   #然用替换通配符得到了所依赖的.o文件名,但实际上并没有.o文件存在		
									  #Makefile会根据规则找到能生成.o文件的gcc命令来得到所需的依赖文件)
		gcc -o $@ $^
	&.o:%.c                            #要生成的.o目标文件依赖于当前文件夹中的.c文件
		gcc -c -o $@ $<                #相当于gcc -c -o target.o target.c
	
	clean :
		rm -f test *.o                 #删除可执行文件test以及所有的.o文件

注意:patsubst ,只是用来替换原文件的后缀名并把这个新的名称赋给变量,并没有生成实质性的文件

分析:

Makefile的执行顺序并不是简单的顺序执行,而是根据要执行目标的依赖自动寻找合适的规则来生成所需要得依赖,如果所需要得依赖又依赖于另一个文件则会继续寻找合适的规则来生成。
在实例代码中,第一次执行$ make test之后:
①Makefile寻找生成test所需的依赖objs(.o文件)

②发现当前文件夹中没有.o文件,寻找可以生成.o文件的规则(&.o:%.c )

③发现生成.o依赖于.c文件,继续寻找.c文件

故上述实例的执行过程是

gcc -c -o $@ $<
gcc -o $@ $^