当前位置: 首页 > news >正文

关于Linux Makefile的一些函数知识foreach、if、call、origin、shell、error和warning

1.foreach函数-遍历

在Makefile中如果想做一些循环或遍历操作时,可以使用foreach函数:

$(foreach VAR,LIST,TEXT)

foreach函数的工作过程是:把LIST中使用空格分割的单词依次取出并赋值给变量VAR,然后执行TEXT表达式。重复这个过程,直到遍历完LIST中的最后一个单词。函数的返回值是TEXT多次计算的结果。

使用示例:假设一个项目,MP3播放器,分别有lcd、keyboad、usb、media目录,分别存放不同的源文件:

# tree.├── keyboard│   └── key.c├── lcd│   └── lcd.c├── makefile├── media│   └── decode.c└── usb    └── usb.c

现在编写一个Makefile,自动搜索各个目录下的C源文件。Makefile的写法如下:

.PHONY: alldirs = lcd usb media keyboardsrcs = $(foreach dir, $(dirs), $(wildcard $(dir)/*))all:    @echo "srcs = $(srcs)"

执行make命令,运行结果如下:

# makesrcs =  lcd/lcd.c  usb/usb.c  media/decode.c  keyboard/key.c

当然,我们也可以根据搜索到的这些C源文件名,生成对应的目标文件名,对应的Makefile如下:

.PHONY: alldirs = lcd usb media keyboardsrcs = $(foreach dir, $(dirs), $(wildcard $(dir)/*.c))objs = $(foreach src, $(srcs), $(subst .c,.o,$(src)))all:    @echo "srcs = $(srcs)"    @echo "objs = $(objs)"

执行make命令,运行结果如下:

# makesrcs =  lcd/lcd.c  usb/usb.c  media/decode.c  keyboard/key.cobjs =  lcd/lcd.o  usb/usb.o  media/decode.o  keyboard/key.o

2.if函数-判断

Makefile中的 if 函数提供了在一个函数上下文中实现条件判断的功能,类似于ifeq关键字,if函数的使用格式如下:

$(if CONDITION,THEN-PART)$(if CONDITION,THEN-PART[,ELSE-PART])

if 函数的第一个参数 CONDITION表示条件判断,展开后如果非空,则条件为真,执行 THEN-PART部分;否则,如果有ELSE-PART部分,则执行ELSE-PART部分。

if函数的返回值即执行分支(THEN-PART或ELSE-PART)的表达式值。如果没有ELSE-PART,则返回一个空字符串。

if 函数使用示例:

.PHONY: allinstall_path = $(if $(install__path), $(install__path), /usr/local)all:    @echo "install_path = $(install_path)"

当我们使用make编译安装一个软件时,通常会指定一个安装路径,如果没有指定的话,则会默认安装在/usr/local目录下。在上面这个Makefile中,我们定义了一个install_path变量,通过if函数来判断这个变量是否为空,来决定最终的安装路径。执行make命令,可以看到运行结果如下:

# makeinstall_path =  /usr/local# make install_path=/optinstall_path = /opt

3.call函数

通过前面的学习我们已经知道:如果想在Makefile中调用GNU make的内置函数,我们使用下面的形式调用:

$(function arguments)${function arguments}

如果想调用用户自定义的函数,则只能使用call函数来间接调用了:

PHONY: alldefine func    @echo "pram1 = $(0)"    @echo "pram2 = $(1)"endefall:    $(call func, hello zixue.com)

我们给函数传递的参数,在函数内部可以使用$(0)、$(1)…直接使用。call函数是唯一一个可以用来创建新的参数化的函数。call函数不仅可以用来调用一个用户自定义函数并传参,还可以向一个表达式传参:

$(call <expression>,<parm1>,<parm2>,<parm3>...)

当 make 执行这个函数时,expression表达式中的参数变量,如$(1),$(2),$(3)等,会被参数parm1,parm2,parm3依次取代。而expression的返回值就是 call 函数的返回值。

.PHONY: allparam = $(1) $(2)reverse_param = $(2) $(1)str1 = $(call param, hello, zixue.com)str2 = $(call reverse_param, hello, zixue.com)all:    @echo "str1 = $(str1)"    @echo "str2 = $(str2)"

执行make命令,运行结果为:

# makestr1 =  hello  zixue.comstr2 =  zixue.com hello

4.origin函数

顾名思义,origin函数的作用就是告诉你,你所关注的一个变量是从哪里来的。函数的使用格式为:

$(origin <variable>)

如果变量没有定义,origin函数的返回值为:undefined,不同的返回值代表变量的类型不同。常见的返回值如下;

  • default:变量是一个默认的定义,比如 CC 这个变量
  • file:这个变量被定义在Makefile中
  • command line:这个变量是被命令行定义的
  • override:这个变量是被override指示符重新定义过的
  • automatic:一个命令运行中的自动化变量

使用示例:

.PHONY: allWEB = www.zixue.comweb_type = $(origin WEB)all:    @echo "web_type = $(web_type)"    @echo "cc_type  = $(origin CC)"    @echo "cmd_type = $(origin CMD)"

执行make命令,运行结果为:

# makeweb_type = filecc_type = defaultcmd_type = undefined# make CMD=pwdweb_type = filecc_type = defaultcmd_type = command line

5.shell函数

如果你想在Makefile中运行shell命令,可以使用shell 函数来完成这个功能。shell 函数的参数是shell命令,它和反引号 `` 具有相同的功能。shell命令的运行结果即为shell函数的返回值。

.PHONY: allcurrent_path = $(shell pwd)all:    @echo "current_path = $(current_path)"

执行make命令,可以看到运行结果:

root@ubuntu:/home/makefile/demo# makecurrent_path = /home/makefile/demo

make提供了两个可以控制make运行方式的函数:error和warning。如果这两个函数在Makefile中使用,当make执行过程中检测到某些错误,就可以给用户提供一些信息,并且可以控制make的是否继续执行下去。

6.error 函数

$(error TEXT…)

使用示例:

.PHONY: allall:    @echo "make command start..."    $(error find a error)    @echo "make command end..."

当执行make命令时,make会执行默认目标all下的命令,当遇到error函数时,就会给用户一个错误提示信息,并终止make的继续执行:

# makemakefile:5: *** find a error.  Stop.

需要注意的是:error函数是在函数被调用时才会提示信息并终止make的继续执行。如果函数出现在命令中,或者出现在一个递归变量的定义里,在读取Makefile时不会出现错误。而只有包含error函数引用的命令执行时,或者包含这个函数的定义变量被展开时,才会提示错误信息TEXT,并终止make的运行。

7.warning 函数

warning函数跟error函数类似,也会给用户提示信息,唯一的区别是:warning函数不会终止make的运行,make会继续运行下去。

$(warning TEXT…)

使用示例:

.PHONY: allall:    @echo "make command start..."    $(warning find a error)    @echo "make command end..."

执行make命令,运行结果为:

# makemakefile:5: find a errormake command start...make command end...

通过运行结果对比可以看到:warning函数和error函数一样,也会产生一个错误提示信息,但是不会终止make的运行。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何使用myabtis log plugin插件展示出数据库查询语句
  • 【C++11】智能指针
  • STM32常用数据采集滤波算法
  • Java | Leetcode Java题解之第400题第N位数字
  • 决策树基础概论
  • Android 13 固定systemUI的状态栏为黑底白字,不能被系统应用或者三方应用修改
  • flutter widget.onPressed回调无效
  • 微软面向所有用户推出 Xbox Game Pass Standard
  • 四、链表————相关概念详解
  • 【数据结构与算法 | 灵神题单 | 合并链表篇】力扣2, 21, 445, 2816
  • Spring 循环依赖原理及解决方案
  • 基于扣子(Coze)打造第一个智能体——个性化对话机器人
  • 【Python基础】Python错误和异常处理(详细实例)
  • Linux s3c2440 开发板上的操作系统实现 ubuntu
  • 前端的面试题
  • .pyc 想到的一些问题
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • Android Studio:GIT提交项目到远程仓库
  • Fastjson的基本使用方法大全
  • golang 发送GET和POST示例
  • go语言学习初探(一)
  • js中的正则表达式入门
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 构造函数(constructor)与原型链(prototype)关系
  • 基于 Babel 的 npm 包最小化设置
  • 前端存储 - localStorage
  • 收藏好这篇,别再只说“数据劫持”了
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 一道面试题引发的“血案”
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​ArcGIS Pro 如何批量删除字段
  • ​flutter 代码混淆
  • ## 1.3.Git命令
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (1)SpringCloud 整合Python
  • (27)4.8 习题课
  • (4)Elastix图像配准:3D图像
  • (PADS学习)第二章:原理图绘制 第一部分
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二十六)Java 数据结构
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (函数)颠倒字符串顺序(C语言)
  • (每日一问)基础知识:堆与栈的区别
  • (算法)硬币问题
  • ****三次握手和四次挥手
  • .bat批处理出现中文乱码的情况
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • //TODO 注释的作用
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @media screen 针对不同移动设备
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell