Makefile小记


基本构成

1
2
3
目标文件列表 : 依赖文件列表 [; 命令]
[命令]
[-/+/@][命令]

  • -:执行本命令若出错,继续而不退出make
  • +:本命令始终被执行,即时运行make时使用了-n-q-t选项。
  • @:执行本命令不回显。

特殊目标

.PHONY.IGNORE.SILENT。。。

利用伪目标生成多个最终目标文件:

1
2
3
4
5
all : a.o b.o c.o
.PHONY : all
a.o :
b.o :
c.o :


隐含规则

1
2
3
4
program : header.h
# make认为program是一个可执行文件,等同于:
program : program.c header.h
gcc -o program program.c

1
2
3
4
program.o : header.h
# .o结尾的目标文件,等同于:
program.o : program.c header.h
gcc -c program.c -o program.o

库:库名(成员名)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mylib : mylib(file1.o)
gcc -c file1.c
ar -ruv mylib file1.o
rm -f file1.o
mylib : mylib(file2.o)
gcc -c file2.c
ar -ruv mylib file2.o
rm -f file2.o
# 进一步简化:
mylib : mylib(file1.o file2.o)
ar -ruv $@ $?
rm -f $?
file1.o :
file2.o :
# 进一步简化:
mylib : mylib(file1.o file2.o)
ar -ruv $@ $?
rm -f $?
# 最终简化:
mylib : mylib(file1.o file2.o)


变量

1
2
3
4
5
VAR = $(RAV) # 递归展开
VAR := $(RAV) # 立即展开,边解释执行边展开
VAR ?= olleh # 未赋值时才赋值
VAR += $(RAV) # 追加
RAV = hello

预定义变量:

除了CCCFLAGSMAKEMAKEFLAGSSHELLPWDARARFLAGSLIBSUFFIXEA以外,还有:

  1. $@:规则中的目标文件名
  2. $*:规则中的目标文件名,去除后缀名
  3. $<:规则中的第一个依赖文件名(含隐含规则)
  4. $^:规则中所有依赖文件列表(去重),空格分隔
  5. $+:规则中所有依赖文件列表(不去重),空格分隔
  6. $?: 所有比目标文件新的依赖文件列表,空格分隔
  7. $%:静态库一个成员名
  8. $>:静态库库名

文件和目录

设置搜索目录

可以通过设置VPATH变量:

1
VPATH = ../src:../foo/include

也可以使用vpath关键字:

1. vpath <pattern> <directories>

1
vpath %.h ../foo/include

2. vpath <pattern>

1
# 清除符合<pattern>的文件指定的搜索目录

3. vpath

1
# 清除所有文件指定的搜索目录

包含其他Makefile

1
2
include foo *.mk $(bar)
-include foo.mk

make -Imake --include-dir 指定目录