规则基本语法

targets : prerequisites
    recipe
# 或者
targets : prerequisites ; recipe
    recipe

赋值

符号 解释
= 延时变量,整个 makefile 展开后,再决定变量的值
:= 立即变量,定义时的赋值立即有效
?= 条件变量(延时),当变量为空时才赋值
+= 追加赋值(延时)

关键字

ifeqelseendififneqifdefifndef

语法

ifeq (value1, value2)
# do something ...
else
# do something ...
endif

功能函数

  • strip:去掉字符串中开头和结尾的空字符,并将中间的多个连续空字符合并为一个空字符

  • shell: 运行 shell 命令

$(shell ls)
  • abspath:生成绝对路径
$(abspath .)    # 返回当前目录的绝对路径
  • lastword:从列表从得到最后一个单词
$(lastword a b c d) # 返回 d
  • dir:路径目录(如果后面是 / 将保持不变)
$(dir a/b)  # 返回 a/,$(dir a/b/) 返回 a/b/
  • filter:匹配模式的单词
$(filter %.c, a.h a.c b.h b.c)  # 返回 a.c b.c
  • filter-out:不匹配模式的单词
$(filter-out %.c, a.h a.c b.h b.c)  # 返回 a.h b.h
  • basename:不要后缀的名字
$(basename a/b/c.h) # 返回 a/b/c
$(basename a/b/c)   # 返回 a/b/c
$(basename a/b.d/c) # 返回 a/b.d/c
  • suffix:取后缀
$(suffix a.c)   # 返回 a
$(suffix a)     # 返回空
  • addprefix:添加前缀
$(addprefix a/, b)  # 返回 a/b
  • addsuffix:添加后缀
$(addsuffix .c, a)    # 返回 a.c

变量

环境变量。比如:$(PWD)、$(HOME)

内置变量

符号 解释
$@ 目标名
$* 从右到左第一个 ‘.’ 前的字符,如果没有 ‘.’ ,$* 为空
$< 第一个依赖文件
$^ 所有的依赖文件(去重)
$+ 所有的依赖文件(不去重)
$? 所有比目标文件新的依赖文件
  • 以上符号都可以和 D、F 搭配,D 代表目录,F 代表文件。例如:$(@D) 表示目标的目录,$(@F) 表示目标的文件名。

模式规则

例如:

%.o : %.c ; command

老式风格的“后缀规则”

  • 现在使用模式规则更好。
  • 所有的后缀需要被 make 通过 .SUFFIXES 预知晓,make 自身预定义了一些后缀,可通过 make -p | grep SUFFIXES 查看。

例如:

.c.o: ; command     # 等价与 %.o: %.c: ; command
# 或者
.c: ; command       # 等价与 % : %.c: ; command
# 注意,规则后面不能跟依赖,如果有了依赖就变成普通的规则

关于当前路径

运行方式 当前运行目录
make 运行 make 时的目录
make -f filename 运行 make 时的目录
make -C dir dir:dir 是 makefile 文件所在的目录
  • $(CURDIR)$(PWD)$(shell pwd) 都可以得到当前目录。
  • 当用了 make -f filename 又想得到 makefile 所在的目录可以用 $(abspath $(lastword $(MAKEFILE_LIST)))

参考资料

  1. Makefile中几种赋值(= := ?= +=).
  2. Makefile 中:= ?= += =的区别 和条件执行.
  3. makefile中获取当前执行路径的命令(PWD).
  4. makefile 分析 – 内置变量及自动变量.
  5. Makefile中的隐式规则.
  6. GNU Make Manual.
  7. make 函数(2)–〉文件名处理函数.
  8. Makefile中的include命令详解