MAKEFILE文件使用说明:
- Make
shell下执行make,查找文件的顺序如下GNUmakefile => makefile => Makefile,通常情况都是用Makefile来命名
make -f xxx ,-f是指定文件名
make 默认执行Makefile的第一个目标
make 后面的参数可以给文件里面的变量赋值,如make TARGET=all
简单事例:
事例一,内含多个目标构建:
事例二,pbc在mac与linux下的构建:
- 规则三要素:目标、依赖、命令
- 每一个命令的起始符必须是Tab,命令可以是shell命令或shell下可执行的程序
- 目标,可以是单个或多个,如 all linux macosx:
- 依赖,可以是一个表达式目标/模式变量,如$(TARGET) : PARAM := xxx,同时也可以是另一个目标
- 命令,跟目标依赖同一行时用’;’与依赖隔开,换行需要用Tab键开头
如下就是一个简单的目标实例:TARGET是目标,pbc-lua53.c是依赖,命令行Tab键开头
$(TARGET) : pbc-lua53.c
$(CC) $(CFLAGS) -shared -o $@ -I../.. -I$(LUADIR) $^ -L../../build -lpbc
Makefile文件可以包含多个规则,当第一个规则的命令在执行的时候发现没有相应的依赖,就从后面的规则中寻找。
最前面的规则是终极目标一定写在最前面,也就是最后要生成的文件。
- 原理,如图
- 读入所有Makefile
- 读入被include的所有Makefile
- 初始化文件中的变量
- 推到隐晦规则,并分析所有规则
- 为所有的目标文件创建依赖关系链
- 根据依赖关系决定哪些目标重新生成
- 执行生成命令
- 自动化变量
- $<:规则中第一个依赖
- $@:规则中目标名
- $^:规则中所有依赖
- $(TARGET):TARGET为声明的变量
- 符号
- =,基本赋值,变量的值会是整个makefile展开后的值
- ?=,如果没有被赋值,就赋值
- :=,覆盖之前的值,变量的值取决于它在makefile中的位置,而不是整个makefile文件展开后的最终值
- +=,添加等号后面的值
- # 注释
- % 自动匹配,如%.o:%.c。目标:依赖
- 反斜杠(),换行符
例,Makefile的内容如下,包含条件表达式:
ifdef DEFINE_VRE
VRE = “Hello World!”
else
endif
ifeq ($(OPT),define)
VRE ?= “Hello World! First!”
endif
ifeq ($(OPT),add)
VRE += “Kelly!”
endif
ifeq ($(OPT),recover)
VRE := “Hello World! Again!”
endif
all:
@echo $(VRE)
敲入以下make命令:
make DEFINE_VRE=true OPT=define 输出:Hello World!
make DEFINE_VRE=true OPT=add 输出:Hello World! Kelly!
make DEFINE_VRE=true OPT=recover 输出:Hello World! Again!
make DEFINE_VRE= OPT=define 输出:Hello World! First!
make DEFINE_VRE= OPT=add 输出:Kelly!
make DEFINE_VRE= OPT=recover 输出:Hello World! Again!
= 与:= 的区别如下
x = foo
y = $(x) bar
x = xyz
执行后y的值为 xyz bar ,而不是 foo bar 。
x := foo
y := $(x) bar
x := xyz
执行后y的值为foo bar。
- 函数
- src=$(wildcard ./*.c),wildcard查找当前目录的所有.c文件返回给src
- obj=$(patsubst ./%.c, ./%.o, $(src)),patsubst是替换当前目录所有.c文件为.o文件
- .PHONEY:clean 的作用,忽略当前目录的clean文件是否存在。假如Makefile文件统计目录也有clean文件,如果没有.PHONEY的声明,是无法执行make clean 操作
- @echo,输出当前行,如果用echo则当前命令行也会输出
- VPATH 文件查找。如 vpath %.c src,表示在src目录查找.c结尾的文件,多个目录用:隔开,如src:src2
- foreach,$(foreach <var>,<list>,<text> ),如
- names := a b c d
- files := $(foreach n,$(names),$(n).o)
- $(files)的值是“a.o b.o c.o d.o”。
- include,引入多个makefile文件,如include platform.mk a.make $(M),表示同时引入platform.mk与a.make文件。include后面只能有一个空格符号