1.makefile中支持条件判断语句
可以根据条件的值来决定make的执行
可以比较两个不同变量或者变量和常量值
ifxxx(arg1,arg2) else endif
注意事项:条件判断语句只能用于控制make实际执行的语句;但是,不能控制规则中命令的执行过程。
工程经验:
条件判断语句之前可以有空格,但不能有Tab字符(’t’)
在条件语句中不要使用自动变量($@, $^, $<)
一条完整的条件语句必须位于同一个makefile中
条件判断类似C语言中的宏,预处理阶段有效,执行阶段无效
make在加载makefile时:
首先计算表达式的值(赋值方式不同,计算方式不同)
根据判断语句的表达式决定执行的内容
2.函数定义及调用
make解释器提供了一系列的函数供makefile调用
在makefile中支持自定义函数实现,并调用执行
通过define关键字实现自定义函数
自定义函数的语法:
函数定义:
define func1 @echo "My name is $(0)" //打印func1函数的第0个参数,本身 endef define func2 @echo "My name is $(0)" //打印func1函数的第0个参数,本身 @echo "Param => $(1)" endef
函数调用:
test : $(call func1) $(call func2, CKY)
深入理解自定义函数:
自定义函数是一个多行变量,无法直接调用
自定义函数是一种过程调用,没有任何的返回值
自定义函数用于定义命令集合,并应用于规则中
make解释器中的预定义函数:
make的函数提供了处理文件名,变量和命令的函数
可以在需要的地方调用函数来处理指定的参数
函数的在调用的地方被替换为处理结果
预定义函数的调用:
问题:为什么自定义函数和预定义函数的调用形式完全不同?
本质剖析:
makefile中不支持真正意义上的自定义函数
自定义函数的本质是多行变量
预定义的call函数在调用时将参数传递给多行变量
自定义函数是call函数的实参,并在call中被执行
.PHONY : test define func1 @echo "My name is $(0)" endef define func2 @echo "My name is $(0)" endef var1 := $(call func1) var2 := $(call func2) var3 := $(abspath ./) var4 := $(abspath test.cpp) test : @echo "var1 => $(var1)" @echo "var2 => $(var2)" @echo "var3 => $(var3)" @echo "var4 => $(var4)"
3.变量与函数的综合实例
实战需求:
自动生成target文件夹存放可执行文件
自动生成objs文件夹存放编译生成的目标文件(*.o)
支持调试版本的编译选项
考虑代码的扩展性
工具原料:
$(wildcard _pattern):获取当前工作目录中满足_pattern的文件或目录列表
$(addprefix _prefix,_names):给名字列表_name中的每一个名字增加前缀_prefix
关键技巧:
(1)自动获取当前目录下的源文件列表(函数调用)
SRCS := $(wildcard *.c)
(2)根据源文件列表生成目标文件列表(变量的值替换)
OBJS := $(SRCS:.c=.o)
(3)对每一个目标文件列表加上路径前缀(函数调用)
OBJS :=
(
a
d
d
p
r
e
f
i
x
p
a
t
h
/
,
(addprefix path/,
(addprefixpath/,(OBJS))
CC := gcc MKDIR := mkdir RM := rm -fr DIR_OBJS := objs DIR_TARGET := target DIRS := $(DIR_OBJS) $(DIR_TARGET) TARGET := $(DIR_TARGET)/hello-makefile.out # main.c const.c func.c SRCS := $(wildcard *.c) # main.o const.o func.o OBJS := $(SRCS:.c=.o) # objs/main.o objs/const.o objs/func.o OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS)) .PHONY : rebuild clean all $(TARGET) : $(DIRS) $(OBJS) $(CC) -o $@ $(OBJS) @echo "Target File ==> $@" $(DIRS) : $(MKDIR) $@ $(DIR_OBJS)/%.o : %.c ifeq ($(DEBUG),true) $(CC) -o $@ -g -c $^ else $(CC) -o $@ -c $^ endif rebuild : clean all all : $(TARGET) clean : $(RM) $(DIRS)
make DEBUG:=true
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)