makefile learn note
参考教程及文档
make语法和规则
target:prerequisites
command1
command2
- target:make命令最终生成的目标文件
- prerequisites:前置依赖条件,通过规则组织依赖文件,最终生成目标文件
- command:如何更新目标文件
- command要以tab键空格,以识别一条command
- 每行的command间是没有关联的,所以使command间有关系可以在一行以分号分隔不同的command
command1;command2
or
command1
command2
...
makefile简单实例
run:
echo "hello world"
@消声:make run command会将命令一起打印出来(回声),可以通过@符号消声
命令间的继承
- command间没有继承关系
- command写在同一行用分号分开
- command写在不同行用连接
make通配符
-
*通配符
匹配任意数量字符
object = *.o 上述object变量的值并不是所有.o文件的集合,object的值就是*.o;
如果想要通配符在变量中展开可以使用:object := $(wildcard *.o)
-
?通配符
匹配除空字符外的单个字符
-
[...]通配符
[start-end]
匹配方括号中的任意字符
-
[^...] or [!...]通配符
匹配不在方括号里的字符
-
{...}
{start..end}
匹配大括号里的所有模式(各模式用逗号分开)
-
[...]和{...}区别
[...]匹配文件不存在会失去匹配功能,{...}可正常展
变量
- 使用变量时需要用$(var)这种形式
- 使用实际的$符时用$$表示:
- 变量替换:$(var:a=b),把变量var中结尾处a字符替换为b字符
- 图1
- 图2
变量放在target外和command处是不同的
自动变量
ITEM | DESC |
---|---|
$@ | 指代target |
$< | 指代第一个前置条件 |
$? | 指代所有比target更新的前置条件 |
$^ | 指代所有前置条件 |
$* | 指代匹配符%匹配的部分 |
$(@D) $(@F) | 分别指代target文件目录名和文件名 |
$(<D) $(<F) | 分别指代第一个前置条件文件目录名和文件名 |
make赋值运算符
ITEM | DESC |
---|---|
= | 在执行时扩展,允许递归扩展 |
:= | 在定义时扩展 |
+= | 只有在该变量为空时才设置值 |
?= | 将值追加到变量的尾端 |
强制执行
- -command:强制执行command
引用其他makefile
-
include make-file-name
-
make 会把包含的makefile放在include的位置
-
如果包含的文件没有找到,先载入其他文件,最后再找一遍,还是没有找到会报出致命信息。忽视无法读取到的文件可以使用-include
文件搜寻
VPATH = path1:path2
文件搜寻有多个路径可以使用分号分隔路径
vpath pattern directory:符合模式文件指定搜索路径
vpath pattern:清楚符合模式的文件的搜索目录
vpath:清楚所有被设置的文件搜索目录
伪目标
.PHONY target
target:
command
多目标
静态目标
自动生成依赖性
显示命令
- make在执行过程中会将当前command显示出来,可以在command前加@,消声
- make -n仅显示命令
- make -s全面禁用所有显示
- make -i忽略全部错误信息
- make -w打印工作路径
嵌套执行make
-
有可能需要跨目录执行make命令
sys: cd dir2;make command
-
主makefile会将显示变量传递到子makefile,不会覆盖子makefile中定义的变量
-
主makefile变量传递到子makefile中可以使用:export variable;
-
主makefile变量不想传递到子makefile中可以使用:unexport variable;
-
export后什么都不加表示传递所有变量
-
SHELL , MAKEFLAGS ,这两个变量不管你是否 export,其总是要传递到下层 Makefile 中
one=this will only work locally
export two=we can run subcommands with this
all:
@echo $(one)
@echo $$one
@echo $(two)
@echo $$two
命令包(宏定义)
define run_model
touch a{0..9}.v
rm a0.v
endef
#Makefile
run:
$(run_model)
条件判断
-
ifeq
ifeq(var1,var2) command1 else command2 endif
-
ifneq
ifneq(var1,var2) command1 else command2 endif
-
ifdef
ifdef var command1 else command2 endif
-
ifndef
ifndef var command1 else command2 endif
字符串处理函数
-
subst字符串替换
$(subst org-str,replace-str,text)
-
patsubst模式字符串替换
$(patsubst org-pat,rep-pat,text)
-
strip去空格函数
- 去掉字符串开头和结尾的空格
$(strip text)
-
findstring查找字符串函数
$(findstring goal,text) #在text中找到目标字符
-
filter过滤函数
$(filter pattern,text) #在text中过滤出符合模式pattern的字符串
-
filter-out反过滤函数
$(filter-out pattern,text) #在text中过滤出不符合模式pattern的字符串
-
sort排序函数
$(sort list) #升序排序
-
word取单词函数
$(word n,text) #取出word中第n个单词
-
wordlist取单词函数
$(wordlist num1,num2,text) #取出字符串中num1到num2处的字符串
- num1大于字符串数量返回空字符
- num2大于字符串数量返回num1到结尾字符
-
words单词个数统计函数
$(words text) #返回text单词个数
-
firstword首单词函数
$(firstword text) #取出text中首个单词