makefile(04)_函数

9.函数定义及调用

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 [email protected] $(OBJS)
    @echo "Target File ==> [email protected]"

$(DIRS) :
    $(MKDIR) [email protected]

# 针对当前文件下的工作目录进行模式替换
$(DIR_OBJS)/%.o : %.c
    ifeq ($(DEBUG),true)
        $(CC) -o [email protected] -g -c $^
    else
        $(CC) -o [email protected] -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);
}

输出结果

原文地址:http://blog.51cto.com/11134889/2108193

时间: 2024-10-11 18:37:13

makefile(04)_函数的相关文章

[连载]JavaScript讲义(04)--- 函数和闭包

点击下载该例子的源代码 [连载]JavaScript讲义(04)--- 函数和闭包,布布扣,bubuko.com

Makefile中的函数

Makefile 中的函数 Makefile 中自带了一些函数, 利用这些函数可以简化 Makefile 的编写. 函数调用语法如下: $(<function> <arguments>) # 或者 ${<function> <arguments>} <function> 是函数名 <arguments> 是函数参数 1.1 字符串函数 字符串替换函数: $(subst <from>,<to>,<text&

[Java]_函数传参的疑惑与思考

问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. 1 void dfs(TreeNode node , int sum , ArrayList<Integer> curPath) 2 void dfs(TreeNode node , int sum , boolean ifExist) 问题:在1号中我可以在方法中修改curPath,在结束函数调用时,变量修改仍然生效.   在2号问题中,我即使在函数中修改了ifExist,结束函数调

Linux makefile教程之函数七[转]

使用函数 ———— 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能.make所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函数的返回值可以当做变量来使用. 一.函数的调用语法 函数调用,很像变量的使用,也是以“$”来标识的,其语法如下: $(<function> <arguments> ) 或是 ${<function> <arguments>} 这 里,<function>就是函数名,m

makefile(08)_打造专业的编译环境

20.打造专业的编译环境(上)_模块Makefile设计 20.0. 实验材料 项目架构:其中各个文件的内容请自己填写. 20.1.大型项目的目录结构(无第三方库) 20.2.项目架构设计分析 项目被划分为不同的多个模块:每个模块用一个文件夹进行管理,文件由inc, src, makefile构成每个模块的对外函数统一放置于common/inc中,如common.h xxxfunc.h 20.3.项目目标 工程项目中不希望源文件夹在编译时被改动(只读文件夹)在编译时自动创建文件夹(build)用

python_字符_函数

一.字符集和字符编码 1.定义 计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的英文.汉字等字符是二进制数转换之后的结果.通俗的说,按照何种规则将字符存储在计算机中,如'a'用什么表示,称为"编码":反之,将存储在计算机中的二进制数解析显示出来,称为"解码",如同密码学中的加密和解密.在解码过程中,如果使用了错误的解码规则,则导致'a'解析成'b'或者乱码. 字符(Character):是一个信息单位,在计算机里面,一个中文汉字是一个字符,一个英文字母是

DayDayUP_Python自学记录[6]_函数学习

Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函数,这被叫做用户自定义函数. 定义一个函数 你可以定义一个由自己想要功能的函数,以下是简单的规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号(). 任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数. 函数的第一行语句可以选择性地使用文档字符串-用于

makefile(01)_初识

0. 声明 本系列(makefile)文章,从零基础开始,通过实验逐步分析makefile的语法特性,并最终打造一个可复用.可移植的专业编译环境.参考:1.DT 唐老师门徒计划课程2.GNU make 手册:http://www.gnu.org/software/make/manual/make.html 1.Make与makefile Make是一个应用程序:接续源程序之间的依赖关系,根据依赖关系自动维护编译工作,执行宿主操作系统中的各种命令. Makefile是一个描述文件:定义了系列的规则

makefile(06)_隐式规则

15.Make的隐式规则 15.1.命令覆盖 问题1:通过各目标的命令拆分写到不同的地方,会发生什么?Makefile中出现同名目标时:依赖:所有的依赖将合并到一起,成为目标的最终依赖命令:当多处出现同一目标的命令时,make发出警告,所有之前定义的命令被最后的命令取代.注意:当使用include包含其他文件(makefile)时,需要确保被包含的文件中的同名目标只有依赖,没有命令:否则,同名目标的命令将被覆盖! 15.2.隐式规则 Make中提供了一些常用的,例行的规则实现,当目标的规则未提供