# Makefile 简明语法 ## 静态模式 静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活。我们还是先来看一下语法: ```Makefile < targets ....> : < target-pattern > : < prereq-patterns ...> ..... ``` 1. targets: 定义了一系列的目标文件,可以有通配符。是目标的一个集合。 2. target-pattern:是指明了 targets 的模式,也就是的目标集模式。 3. prereq-patterns 是目标的依赖模式,它对 target-parrtern 形成的模式再进行一次依赖目标的定义。 例如: ```Makefile OBJS = a.o b.o $(OBJS) : %.o : %.c gcc -c $< -o $@ all: $(OBJS) ``` 这两条命令的功能就是,大目标是 OBJS,这个 OBJS 就是各种“.o”文件,“%.o”是指“\$(OBJS)”中全部“.o”文件,而“%.c”就将对应的“.o”文件替换为同名的“.c”文件。后续的命令,结合了 2 个自动化变量,“\$<” 表示依赖对象集中的第一个,这里指对应的“.c”文件;“$@” 则代表了目标集,这里指对应的“.o”文件。所以上述 Makefile 的功能就是要遍历所有的“.c”文件,对所有的“.c”文件进行编译,然后编译生成对应的“.o”文件。 有时,targets 是不需要的,可以简写如下: ```Makefile OBJ1 = a.o b.o OBJ2 = c.o d.o %.o : %.c gcc -c $< -o $@ all: $(OBJ1) $(OBJ2) ``` 这时 Makefile 默认对所有的“.c”文件应用该规则生成对应的“.o”文件(a.c、b.c、c.c、d.c 都使用 gcc -c $< -o $@ 规则进行编译)。 ## FORCE ```Makefile FORCE: ; .PHONY: FORCE : FORCE ``` 如果一个规则没有命令或者依赖,而且它的目标不是一个存在的文件名,在执行此规则时,目标总会被认为是最新的。也就是说,这个规则一旦被执行,make 就认为它所表示的目标已经被更新过。当将这样的目标(FORCE)作为一个规则的依赖时(如上的 vmlinux: ),由于依赖总被认为是被更新过的,所以作为依赖所在的规则定义的命令总会被执行。 ## 获取 git comiit 提交 ### 获取 branch 名 ```Makefile GIT_BRANCH=$(shell git branch | sed -n '/\* /s///p') ``` ### 获取 commit 号 ```Makefile GIT_COMMIT=$(shell git log --pretty=format:'%H' -1) ```