79 lines
2.5 KiB
Markdown
79 lines
2.5 KiB
Markdown
# Makefile 简明语法
|
||
|
||
**注意,Makefile 规则中的每一行都在其自己的 shell 实例中运行。**
|
||
|
||
## 静态模式
|
||
|
||
静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活。我们还是先来看一下语法:
|
||
|
||
```Makefile
|
||
< targets ....> : < target-pattern > : < prereq-patterns ...>
|
||
<commands>
|
||
.....
|
||
```
|
||
|
||
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
|
||
|
||
<target>:<dependences> 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)
|
||
```
|
||
|
||
### 获取最后一个 tag
|
||
|
||
```Makefile
|
||
GIT_LAST_TAG=$(shell git describe --tags `git rev-list --tags --max-count=1`)
|
||
```
|