makefile个人笔记

基本形式

target: prerequisites(also can be targets)
	command

target可以为文件名,也可以为一个随意的字符串,make默认执行第一个有效target
执行逻辑:

  1. 检查前置条件,并达成所有前置条件
  2. 执行所有的command

扩展形式(可有部份文件不触发make)

target: prerequisites(also can be targets)|prerequisites(changes will not remake)
	command

匹配模式

target:target-pattern:prereq-patterns:
	command
objs:=a.o b.o
all:$(objs) #
$(objs):%.o:%.c
	cc -c $< -o $@
.PHONY:clean
clean:
	rm *.o
a.o b.o:%.o:%.c #只会生成a.o
	cc -c $< -o $@
.PHONY:clean
clean:
	rm *.o

双冒号模式(可存在多个相同目标,每个目标由不同的依赖触发)

test: a.c
	cc -c $< -o a.o
test: b.c
	cc -c $< -o b.o

会有警告并只执行后者

test:: a.c
	cc -c $< -o a.o
test:: b.c
	cc -c $< -o b.o

打印一个 hello

test:
	echo hello 

使用@可以不回显执行的命令

test:
	@echo hello 

make支持的变量仅有字符串类型

定义方式

  1. = = =,运行时展开,可使用先于声明
  2. : = := :=,编译时展开
  3. ? = ?= ?=,条件定义
  4. d e f i n e define define,多行变量

变量定义1

运行时展开变量,被读入的变量如果是引用其它的变量,则直到其被使用时,
才对其进行展开,这种变量使用 = = = 号赋值。

var1=$(val2)
val2=$(val3)
val3="hello "world
test:
	@echo $(var1)

变量定义2

编译时展开变量,使用符号 : = := :=
无法使用在该变量定义的代码前无定义的变量。

var1:=1
var2:=$(var1)2"3"
test:
	@echo $(var2)

变量定义3

多行变量

define var
echo foo
echo hello
endef
test:
	$(var)

类似程序中的局部变量

var=fuck
all:test
	echo $(var)
test:var=hello
test:
	echo ${var}

模式匹配版本

var=fuck
%haha:var=hahafuck
all:test ahaha fuckhaha

test:
	echo $(var)
ahaha:
	echo $(var)
fuckhaha:
	echo $(var)

字符串末位替换

写法1

var2:=123456
var1:=$(var2:456=abc)
test:
	@echo $(var1)

写法2

var2:=123456
var1:=$(var2:%456=%abc)
test:
	@echo $(var1)

写法3

var2:=123456
var1:=$(var2:%456=%abc)
test:
	@echo $(patsubst %456,%abc,$(var2))

预定义变量

$@:
注意,模式匹配的单个目标会展开成多个目标

test:atest btest
	@echo test
%test:
	@echo $@
test fuck:
	@echo $@

条件判断

  1. ifdef,ifndef,ifeq,ifneq,else,endif
var=fuck
test:
ifeq ($(var),fuck)
	echo yes
else 
	echo no
endif
	echo fuck

注意if表示不为空取后者,没有与else endif配合

var=cd
test:
	echo $(if $(var),${var},c)

循环

test:
	echo $(foreach i,a b c d, $(i)hello)

函数

注意,使用call

var=$(2)$(1)
test:
	echo $(call var,a ,b)
listf = $(filter $(if $(2),$(addprefix %.,$(2)),%),\
		  $(wildcard $(addsuffix $(SLASH)*,$(1))))
test:
	echo $(call listf,*.c)

不展开变量的函数

var=${hello}
hello=fuck
test:
	echo $(var)
	echo $(value var)

eval函数

  1. 基础用法
    将变量定义的字符串转成makefile代码
$(eval var=hello)
all:
	@echo $(var)
  1. 将多行文本转化成makefile代码
define macrotarget
all:
	@echo macrotarget
endef
$(eval $(call macrotarget))
  1. 配合makefile变量和macro参数使用
var=var
define mfunc
$(1):
	@echo $(var)
	@echo $(1)
endef
$(eval $(call mfunc,hello))
  1. 二次展开
var1=var2
var2=var3
define two
$${${var1}}=test
endef
$(info $(call two))
$(eval $(call two))
all:
	echo ${var3}
var2=var3
$(eval ${var2}=test)
all:
	echo ${var3}

预定义的文本处理函数

调用格式$ ( f u n c t i o n , p a r a m s ) (function,params) (function,params)
局部替换函数

全局替换

$(subst FROM,TO,TEXT) #将text中的FROM换成TO

var=fuckfuck
test:
	echo $(subst fuck,hello,${var})

尾部替换

var=a.c.c #针对变量的简洁写法
test:
	echo $(patsubst %.c,%.o,a.c.c)
	echo $(var:.c=.o) #针对变量的简洁写法

空格去除

var=     a  b c
test:
	echo $(strip $(var))

查找匹配字符串,成功返回该字符串,否则空串

test:
	echo $(findstring abc,abcd)
	echo $(findstring abc,abdc)

过滤掉不符合模式的字符串

test:
	echo $(filter %.c,a.c b.c b.c.c a.o)

反向过滤

test:
	echo $(filter-out %.c,a.c b.c b.c.c a.o)

排序(首字母升序)

test:
	echo $(sort a bc cb A B C)

取单词

test:
	echo $(word 1, a bc cb A B C)

取多个单词

test:
	echo $(wordlist 1,3, a bc cb A B C)

计算有多少个单词

test:
	echo $(words 1,3, a bc cb A B C)

预定义文件处理函数

取目录

test:
	echo $(dir /mnt/a/a.c /test/a.a)

取文件名

test:
	echo $(notdir /mnt/a/a.c a.c)	

取文件名后缀(没后缀则忽略,不产生空串)

test:
	echo $(suffix /mnt/a/a.c b a.c)	

取文件名(不包括后缀)

test:
	echo $(basename /mnt/a/a.c b a.c)

给文件添加后缀

test:
	echo $(addsuffix .haha, /mnt/a/a.c b a.c)	

给文件添加前缀(注意文件名不要包括目录)

test:
	echo $(addprefix hello_, /mnt/a/a.c b a.c)

文件名拼接

test:
	echo $(join a b,.a .b)

列出当前目录下匹配成功的文件名集合

test:
	echo $(wildcard *.c)

自动化变量

空目标默认不是最新的
$@
显示为test

test:
	echo $@ 

$%

test(hello):
	echo $@ $%

$<

test(hello):r1 r2 r3
	echo $<
r1 r2 r3:

? 假设 a . o 存在, b . o 不存在, ? 假设a.o存在,b.o不存在, ?假设a.o存在,b.o不存在,?=b.o

ab.a:a.o b.o
	echo $?
	ar rcs ab.a a.o b.o 

$^ 表示所有依赖

test:c d e f
	echo $^
a b c d:

二次扩展

.SECONDEXPANSION:
main_OBJS := main.o try.o test.o
lib_OBJS := lib.o api.o

all: main lib
main lib: $$($$@_OBJS)
	echo $^

main.o try.o test.o:

lib.o api.o:
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值