记不住Makefile 怎么写?试试我的cheat sheet吧!

记不住Makefile 怎么写?试试我的cheat sheet吧!

机制

target: prerequisites
	commands
	
commands可以为空

自动变量

$@ 表示目标文件的名称,包含扩展名
$^ 表示所有的依赖文件,以空格隔开,不重复
$< 表示第一个依赖文件的名称

$* 表示目标文件的名称,不包含扩展名
$+ 表示所有的依赖文件,空格隔开,可以重复

$? 依赖项中,所有比目标文件新的依赖文件

内置变量

MAKECMDGOALS 命令行指定的维护目标

内置函数

文件名处理函数

$(wildcard *.cpp test/*.cpp) 获取所有.cpp 文件
$(dir src/foo.c sum.txt) 获取文件目录
$(notdir src/foo.c sum.txt)  获取文件名(含扩展名)
$(suffix src/foo.c src-1.0/bar.c hacks) 获取文件后缀
$(basename src/foo.c src-1.0/bar.c hacks) 去除文件后缀
$(addsuffix .c,foo bar)  添加后缀
$(addprefix src/,foo bar)   添加前缀
$(join a b , .c .o)  链接2个list中字符,2个list中的字符数量需要一致

字符串处理函数

$(subst aa,AA,aabbaa aAfd) 直接替换字符,从参数3中将参数1的字符改成参数2的字符
$(patsubst %.cpp,%.o,add.cpp bar.cpp) 按格式替换字符,通配符 % 表示任意长度的字串
$(strip, add.cpp bar.cpp ) 去掉开头和结尾的空白字符
$(findstring a,a b c) 在参数2中查找参数1字符,找到了返回对应字符,没找到返回空字符
$(filter %.c %.s,${sources}) 从参数2中保留参数1中指定的字符
$(filter-out ,) 和filter相反,去掉指定的字符
$(sort foo bar lose foo) 对列表中的字符串进行升序排序并去重
$(word N,TEXT)  从text中取N个单词
$(wordlist S,E,TEXT)  取从S开始到E结束的单词
$(words TEXT)  统计text中单词数量
$(firstword NAMES…) 取第一个单词

log函数

$(info/warning/error ) 分别打印3个级别的log

foreach函数

$(foreach ,,)
dirs := a b c d
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
将  中的参数逐一取出放到  变量中,然后再执行  中的表达式。
循环执行中:每执行一次循环都会返回一个字符串
循环执行结束:返回汇总的字符串(不同字串以空格分隔)

call函数

$(call ,,,,...)
调用自定义的函数或者表达式,可传参

shell函数

$(shell )
调用shell 命令,返回的是命令的执行结果

eval函数

$(eval )
eval 可以将  中的内容作为makefile的一部分,然后按照makefile的语法解析这些内容,无返回值。该函数在执行时会对参数展开两次,可以理解为第一次是eval函数检查语法,第二次是解析 内容。

条件判断

ifeq (first, second) ... else ifeq ... else ... endif
ifeq 'first' 'second'
ifneq (first, second)

ifdef VARIABLE_NAME ... else ifdef ... else ... endif
ifndef VARIABLE_NAME

自定义函数

define run_demo_makefile
@echo -n "Hello"
@echo " Makefile!"
@echo "这里可以执行多条 Shell 命令!"
endef

all:
	$(run_demo_makefile)

特殊符号

- 符号: 忽略被修饰命令的返回错误,如果这些命令遇到错误,也不会终止make运行
clean :
	-rm $(objects)
	
@ 符号:取消被修饰命令的自我回显,只显示命令的执行结果
@echo $(x)

* 通配符:代表n个字符
OBJ = ${wildcard *.o}

% 模式匹配字符:用于模式规则中,代表前后相同的n个字符
%.o : %.c
    $(CC) -c $(CFLAGS) $< -o $@

赋值方式

= 展开赋值,即makefile 解析完之后的最终赋值
:= 直接赋值,即在当前位置的值
?= 无值则赋值,变量在当前位置没有值则赋值
+= 追加赋值,在当前值的基础上追加赋值

伪目标

.PHONY: clean  执行make时输入的目标。

参数传递

Makefile的参数和变量会自动的传递到下层的makefile和其调用的shell脚本里。

示例1

CC = gcc 
LD = gcc

SRCS = $(wildcard *.c)
OBJS = $(patsubst %c, %o, $(SRCS))
TARGET = Hello

.PHONY:all clean

all: $(TARGET)

$(TARGET): $(OBJS)
	$(LD) -o $@ $^

%.o:%.c
	$(CC) -c $^

clean:
	rm -f $(OBJS) $(TARGET)

你可能感兴趣的:(老亚瑟的技术备忘录,linux)