makefile-04-函数

    xiaoxiao2022-07-12  155

    9.函数定义及调用http://blog.51cto.com/11134889/2108193

    Makefile中支持函数的概念,make解析器提供了一系列函数供Makefile使用。同时可以自定义函数。

    9.1.自定义函数

    在Makefile中支持自定义函数的实现,并调用执行,通过define关键字来实现自定义函数。

    函数定义的语法规则:

    自定义函数的本质:

    1.自定义函数其实是一个多行变量,无法直接调用;通过call 关键字来使用(call的作用就是将实参替换到函数体对应的位置)

    2.自定义函数是一种过程调用,没有任何的返回值;

    3.用于定义命令集合,并应用于规则中。

    示例:

    .PHONY : test define func1 @echo "My name is $(0)"endef define func2 @echo "My name is $(0)" @echo "Param 1 => $(1)" @echo "Param 2 => $(2)"endef var := $(call func1) new := $(func1) test : @echo "new => $(new)" @echo "var => $(var)" $(call func1) #@echo My name is func1 $(call func2, D.T.Software, delphi_tang)

    输出结果:

    9.2.预定义函数

    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)"

    输出结果:

     

    10.变量与函数的综合运用

    10.1.实战需求:

    自动生成target文件夹存放可执行程序,生成objs文件夹存放编译生成的目标文件(*.o)

    支持调试版本的编译选择(通过预编译宏实现),考虑代码的扩展性(自定义变量)

    10.2.工具原料:

    $(wildcard _pattern),获取当前工作目录中满足_pattern的文件或者目录

    $(addprefix _prefix _name),给名字列表_name中的每一个名字增加前缀_prefix

    10.3.关键技巧:

    1.自动获取当前目录下的源文件列表(函数调用),SRCS := $(wildcard *.c)

    2.根据文件列表生成目标文件列表(变量指定替换)OBJS := $(SRCS:.c=.o)

    3.对每一个目标文件列表加上路径前缀(函数调用)OBJS := $(addprefix path/, $(OBJS))

    规则中的模式替换:

    这两种模式替换的区别在于,后者的模式替换目标来自于一个变量var,前者的目标来自一个指定的文件夹。

    编译规则的依赖:

    最终程序:

    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)

    源文件main.c

    extern void foo(); int main(){ foo(); return 0; }

    源文件const.c

    const char* g_hello = "hello makefile";

    源文件func.c

    #include "stdio.h" extern char* g_hello; void foo(){ printf("void foo() : %s\n", g_hello); }

    输出结果

     

     

    最新回复(0)