target ... : prerequisites ...
command
...
(1)command一定要以Tab开头
(2)prerequisites中若有一个文件比target新,或target不存在,command命令就会执行。
(1)在当前目录下找Makefile或makefile
(2)找第一个target,作为最终的目标文件
(3)若target不存在或依赖的修改时间比它新,就执行后面定义的命令
(4)依次以依赖循环下去,直到生成最终目标
定义:OBJ = main.o test.o
使用:$(OBJ)
make找到*.o那么*.c就是其依赖文件。
(1)显式规则:如何生成目标文件
(2)隐晦规则:自动推导
(3)变量定义:变量一般是字符串
(4)文件指示:①引用另一个Makefile ②指定有效部分
(5)注释:#
(6)命令必须tab开头
make默认寻找GNUmakefile、makefile、Makefile,也可使用-f或--file指定
include ...
(1)前面可以有空格,但不能是tab。
(2)默认在当前目录寻找,然后/usr/local/bin或/usr/include
(3)-I 或 --include-dir指定目录
(4)未找到文件生成警告消息,继续执行,再次寻找时会产生致命信息
(5)-include
(1)读Makefile
(2)include
(3)初始化变量
(4)推导隐晦规则
(5)创建依赖关系链
(6)根据依赖关系,决定哪些目标重新生成
(7)执行命令
*, ?, [...]
.PHONY : clean
避免和文件重名
$@所有目标集合
...
targets 定义了一系列目标文件
target-parrtern 指明模式
prereq-patterns 目标的依赖模式
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
-M 自动寻找源文件中包含的头文件,并生成依赖关系
-MM 避免包含标准库头文件
%d: %.c
@set -e; rm -rf $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed `s, \($*\)\.o[ :]*,\1.o $@ : ,g` < $@.$$$$ > $@; \
rm -f $@.$$$$
① @在命令前,不显示执行的命令
② make -n 或 --just-print只显式不执行
① 后一条命令依赖前一条命令的结果,需写在一行用";"分开
① 命令出错终止执行
② 加横杆-,忽略错误
③ make -i 或者 --ignore-errors,忽略所有命令的错误
subsystem:
cd subdir && $(MAKE)
或
subsystem:
$(MAKE) -C subdir
① Makefile变量可以传递到下级,但不会覆盖,除非指定-e参数
② export
③ unexport
define run-yacc
yacc $(firstwword $^)
mv y.tab.c $@
endef
foo.c: foo.y
$(run-yacc)
由字符、数字、下划线组成,大小写敏感
使用$字符,$$
foo = $(bar)
bar = 123
x := foo
y := $$(x)
x := later
FOO ?= 456
x = test.c
x += main.c
make CC=gcc
override CC = g++
override CC := g++
define two-lines
echo foo # 可以是函数、命令、文字、其他变量
echo $(bar)
endef
① Makefile中可使用环境变量,make参数和里面定义的变量会覆盖环境变量
② 若make -e则环境变量覆盖他们
③ 上层Makefile中变量可使用export声明传递到下层
%.o: CFLAGS = -O
条件表达式可以是比较变量的值、变量、常量
@echo ""
else
@echo ""
endif
①
endif
②
else
endif
③
ifeq (
ifeq '
ifeq "
ifeq "
ifeq '
ifdef foo #测试变量是否有值
$(
${
bar := $(subst $(sub), $(value), $(main))
$(subst
$(patsubst
$(strip
$(findstring
$(filter
$(filter-out
$(sort ) # 给字符串中的单词升序排序
$(word
$(wordlist ,
$(words
$(firstword
$(dir
$(suffix
$(basename
$(addsuffix
$(addprefix
$(join
$(foreach , ,
names := a b c d
files := $(foreach n,$(names),$(n).o)
$(if
$(if
$(call
reverse = $(1) $(2)
foo = $(call reverse, a, b)
files := $(shell echo *.c)
生成shell程序来执行命令,注意性能问题
0 成功,1 错误,2 make -q,使得一些目标不需要更新
① make install,make clean
② "="或"-"开头时会被解析成参数或变量
③ MAKECMDGOALS环境变量指定目标
④ 常用功能
all :编译所有目标
clean:删除创建的文件
print:列出改变过的源文件
tar:打包源程序
dist:创建压缩文件
TAGS:更新所有目标,以备完整地重编译使用
check和test:测试Makefile的流程
参数:-n、--just-print、--dry-run,--recon
① -b和-m忽略和其他make版本的兼容性
② -B和--always-make重编译
③ -C和--directory=
④ -e和--environment-overrides指明环境变量的值覆盖makefile中值
⑤ -f、--file、--makefile指定文件
⑥ -h和--help显式帮助信息
⑦ -i和--ignore-errors忽略执行错误
⑧ -I 和--include-dir=指定包含makefile的搜索目标
⑨ -j和--jobs指定同时运行命令个数
11 -q和--question检查目标是否需要更新
12 -r和--nobuiltin-rules禁止make使用任何隐含规则
① C语言,
② c++,
③ 汇编和汇编预处理,
① 命令变量
AR :ar 函数库打包
AS :as 汇编语言编译
CXX :g++
CPP :c程序预处理器
RM :rm -rf
② 命令参数变量
ARFLAGS :rv 函数库打包程序AR的参数
ASFLAGS :汇编语言编译器参数
CFLAGS :c语言编译器参数
CXXFLAGS:c++语言编译器参数
CPPFLAGS:c预处理器参数
LDFLAGS :链接器参数
产生中间文件
1、目标中%表示对文件名的匹配,%.c或s.%.c
2、示例
%.o : %.c
$(CC) -c $(CFLAGS) $(LDFLAGS) $< -o $@
$< 依赖挨个值,$@ 目标挨个值
把模式中所定义的一系列的文件自动地挨个取出。
$@ 目标文件集,若有多个目标匹配于目标中模式定义的集合
$% 仅当目标是函数库文件中,表示规则中的目标成员名
$< 依赖目标中的第一个目标名字
$? 所有比目标新的依赖目标的集合
$^ 所有依赖目标的集合,去除重复
$+ 与$^相似,但不去重
$* 表示目标模式中%及其之前的部分。如dir/a.foo.b模式a.%.b, $*为dir/a.foo
$(@D) 表示$@的目录部分
$(@F) 表示$@的文件部分
$(*D)、$(*F) 与前两个相似,但不包含后缀
$( $(^D)、$(^F) 表示所有依赖的目录和文件部分,无相同 $(+D)、$(+F) 表示所有依赖的目录和文件部分,可相同 $(?D)、$(?F) 表示被更新的依赖的目录和文件部分 ① 依赖目标的茎会传给目标 ② 有斜杆时会先将目录部分移开,匹配成功后再加回去。 %.o会去找bar.o, 没有的话去找bar.c来生成bar.o cc -c bar.c -o bar.o ar r foo.a bar.o rm -rf bar.o .c.a: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $*.o $(AR) r $@ $*.o $(RM) $*.o 等效: (%.o) : %.c $(CC) $(CFLAGS) $(CPPFLAGS) -C $< -o $*.o $(AR) r $@ $*.o $(RM) $*.o 并行机制-j可以损坏函数库 ################################################# BIN = main OBJS = a.o b.o c.o CFLAGS = -Werror -Iinclude CC = gcc DEPENDE_FILES := $(patsubst %, .%.d, $(OBJS)) DEPENDE_FILES := $(wildcard $(DEPENDE_FILES)) $(BIN): $(OBJS) $(CC) -o $@ $^ ifneq ($(DEPENDE_FILES),) include $(DEPENDE_FILES) endif %.o : %.c $(CC) $(CFLAGS) -c -o $@ $< -MD -MF [email protected] clean: rm *.o $(BIN) distclean: rm $(DEPENDE_FILES) .PHONY: clean ################################################# 参考《一起来写Makefile》 欢迎转载请注明出处:海漩涡 http://blog.csdn.net/tanhuifang520 8、模式匹配
十、更新函数库文件
1、隐含规则
2、后缀规则
十一、实例