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

Linux Makefile文本处理函数知识详解

1.Makefile函数

GNU make 提供了大量的函数用来处理文件名、变量、文本和命令。通过这些函数,用户可以节省很多精力,编写出更加灵活和健壮的Makefile。函数的使用和变量引用的展开方式相同:

$(function arguments)${function arguments}

关于函数的使用格式,有以下需要注意的地方:

  • 函数主要分为两类:make内嵌函数和用户自定义函数。对于 GNU make内嵌的函数,直接引用就可以了;对于用户自定义的函数,要通过make的call函数来间接调用。
  • 函数和参数列表之间要用空格隔开,多个参数之间使用逗号隔开。
  • 如果在参数中引用了变量,变量的引用建议和函数引用使用统一格式:要么是一对小括号,要么是一对大括号。

函数使用示例:如果我们想要获取某个目录下所有的C文件列表,可以使用扩展通配符函数:wildcard

SRC  = $(wildcard *.c)HEAD = $(wildcard *.h)all:    @echo "SRC = $(SRC)"    @echo "HEAD = $(HEAD)"

在当前目录下,我们新建一些C文件和H文件,然后使用make命令:

# lsadd.c  add.h  hello.c  main.c  makefile  sub.c  sub.h# makeSRC = hello.c main.c add.c sub.cHEAD = add.h sub.h

1.1用户自定义函数

GNU make提供了大量的内嵌函数,大大方便了用户Makefile的编写。但有时候根据需要,用户也可以自定义一些函数,然后在Makefile中引用它们:

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

用户自定义函以define开头,endef结束,给函数传递的参数在函数中使用$(0)、$(1)引用,分别表示第1个参数、第2个参数…对于用户自定义函数,在Makefile中要使用call函数间接调用,各个参数之间使用空格隔开:

# makepram1 = funcpram2 =  hello zhaixue.cc

2.Makefile文本处理函数 

GNU make提供了一系列文本处理函数:subst、patsubst、strip、findstring、filter、filer-out、sort、word、wordlist、words、fistword。接下来我们一一讲解:

2.1subst函数

subst函数用来实现字符串的替换,将字符串text中的old替换为new

$(subst old,new,text)

编写一个Makefile,将当前目录下的所有c文件的名称xx.c转换为xx.o

.PHONY: allSRC  = $(wildcard *.c)OBJ  = $(subst .c,.o,$(SRC))all:    @echo "OBJ = $(OBJ)"    @echo $(subst banana, apple, "banana is good, I like banana")

执行make命令,可以看到执行结果:字符串中的banana替换成了apple,SRC变量中的所有.c 替换成了 .o:

# lsadd.c  add.h  hello.c  main.c  makefile  sub.c  sub.h# makeOBJ = hello.o main.o add.o sub.o apple is good, I like  apple

2.2patsubst函数

patsubst函数主要用来模式替换:使用通配符 % 代表一个单词中的若干字符,在PATTERN和REPLACEMENT如果都包含这个通配符,表示两者表示的是相同的若干个字符,并执行替换操作。

$(patsubst PATTERN, REPLACEMENT, TEXT)

如果我们想把某个目录下的所有.c文件皆为的文件名转换为以.o皆为的目标文件名,相比subst,使用patsubst会更加方便:

.PHONY: allSRC  = $(wildcard *.c)OBJ  = $(patsubst %.c, %.o, $(SRC))all:    @echo "OBJ = $(OBJ)"

SRC变量中包括多个字符串,代表各个文件名,各个字符串之间使用空格隔开,使用OBJ变量保存转换后的字符串。在当前目录下直接执行make,可以看到运行结果:

# lsadd.c  add.h  hello.c  main.c  makefile  sub.c  sub.h# makeOBJ =  hello.o  main.o  add.o  sub.o

在Makefile中,如果我们已经得到了需要编译的C文件,想要得到它们对应的目标文件,经常使用上面的patsubst函数进行转换。

2.3strip函数

strip函数是一个去空格函数:一个字符串通常有多个单词,单词之间使用一个或多个空格进行分割,strip函数用来将多个连续的空字符合并成一个,并去掉字符串开头、末尾的空字符。空字符包括:空格、多个空格、tab等不可显示的字符。

.PHONY: allSTR =     hello a    b   cSTRIP_STR = $(strip $(STR))all:    @echo "STR = $(STR)"    @echo "STRIP_STR = $(STRIP_STR)"

执行make后的结果:

# makeSTR = hello a    b   cSTRIP_STR = hello a b c

strip函数经常用在条件判断语句的表达式中,去掉多余的空格等因素,确保表达式比较的可靠和健壮。

ifeq ($(strip $(foo)),)    echo "foo is empty"endif

2.4findstring 函数

findstring函数用来查找一个字符串。使用格式如下:

$(findstring FIND, IN)

findstring函数会在字符串IN中查找“FIND”字符串,如果找到,则返回字符串FIND,否则,返回空。

.PHONY: allSTR =     hello a    b   cFIND = $(findstring hello, $(STR))all:    @echo "STR = $(STR)"    @echo "FIND = $(FIND)"

执行make,运行结果为:

# makeSTR = hello a    b   cFIND = hello

2.5filter 函数

filter函数用来过滤掉一个指定的字符串,使用格式如下:

$(filter PATTERN…,TEXT)

filter函数用来过滤掉字符串TEXT中所有不符合PATTERN模式的单词,只留下符合PATTERN格式的单词。

.PHONY: allFILE = a.c b.h c.s d.cppSRC = $(filter %.c, $(FILE))all:    @echo "FILE = $(FILE)"    @echo "SRC = $(SRC)"

执行make,运行结果为:

# makeFILE = a.c b.h c.s d.cppSRC = a.c

2.6filter-out 函数

filer-out函数是一个反过滤函数,功能和filter函数恰恰相反:该函数会过滤掉所有符合PATTERN模式的单词,保留所有不符合此模式的单词。

.PHONY: allFILE = a.c b.h c.s d.cppSRC = $(filter-out %.c, $(FILE))all:    @echo "FILE = $(FILE)"    @echo "SRC = $(SRC)"

在上面的Makefile中,使用filter-out %.c 过滤掉所有的.c文件。执行make,运行结果为:

# makeFILE = a.c b.h c.s d.cppSRC = b.h c.s d.cpp

2.7sort函数:单词排序

$(sort LIST)

sort函数对字符串LIST中的单词以首字母为准进行排序,并删除重复的单词。

.PHONY: allFILE = a.c b.h c.s d.cppSRC = $(filter-out %.c, $(FILE))all:    @echo "FILE = $(FILE)"    @echo "SRC = $(SRC)"

执行make,运行结果为:

# makeLIST = banana pear apple peach apple orangeSTR = apple banana orange peach pear

2.8word函数:取单词

word函数的作用是从一个字符串TEXT中,按照指定的数目N取单词:

 $(word N,TEXT)

函数的返回值是字符串TEXT中的第N个单词。如果N的值大于字符串中单词的个数,返回空;如果N为0,则出错。

.PHONY: allLIST = banana pear apple peach orangeword1 = $(word 1, $(LIST))word2 = $(word 2, $(LIST))word3 = $(word 3, $(LIST))word4 = $(word 4, $(LIST))word5 = $(word 5, $(LIST))word6 = $(word 6, $(LIST))all:    @echo "word1 = $(word1)"    @echo "word2 = $(word2)"    @echo "word3 = $(word3)"    @echo "word4 = $(word4)"    @echo "word5 = $(word5)"    @echo "word6 = $(word6)"

执行make,运行结果为:

# makeword1 = bananaword2 = pearword3 = appleword4 = peachword5 = orangeword6 =

如果N的值为0,Makefile含有下面的语句:

word0 = $(word 0, $(LIST))

则会报错:

makefile:9: *** first argument to 'word' function must be greater than 0.  Stop.

2.9wordlist函数:取字串

wordlist函数用来从一个字符串TEXT中取出从N到M之间的一个单词串:

$(wordlist N, M, TEXT)

N 和 M都是从1开始的一个数字,函数的返回值是字符串TEXT中从N到M的一个单词串。当N比字符串TEXT中的单词个数大时,函数返回空。

.PHONY: allLIST = banana pear apple peach orangesub_list = $(wordlist 1, 3, $(LIST))all:    @echo "LIST = $(LIST)"    @echo "sub_list = $(sub_list)"

执行make时,wordlist函数会将字符串LIST中的前三个单词赋值给sub_list:

# makeLIST = banana pear apple peach orangesub_list = banana pear apple

2.10words函数:统计单词数目

words函数用来统计一个字符串TEXT中单词的个数:

$(words TEXT)

words函数的返回值为字符串TEXT中单词的个数。

.PHONY: allLIST = banana pear apple peach orangeall:    @echo "LIST = $(LIST)"    @echo "LIST len = $(words $(LIST))

执行make,运行结果为:

# makeLIST = banana pear apple peach orangeLIST len = 5

2.11firstword函数:取首个单词

firstword函数用来取一个字符串中的首个单词。

$(firstword NAMES…)$(word 1,TEXT)

firstword函数其实就相当于$(word 1,TEXT):

.PHONY: allLIST = banana pear apple peach orangeall:    @echo "LIST = $(LIST)"    @echo "first word = $(firstword $(LIST))"

执行make,运行结果为:

# makeLIST = banana pear apple peach orangefirst word = banana

相关文章:

Linux Makefile文本处理函数知识详解

1.Makefile函数 GNU make 提供了大量的函数用来处理文件名、变量、文本和命令。通过这些函数,用户可以节省很多精力,编写出更加灵活和健壮的Makefile。函数的使用和变量引用的展开方式相同: $(function arguments)${function arguments}关于…...

Rust的数据类型

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust到底值不值得学,之一 -CSDN博客 Rust到底值不值得学,之二-CSDN博客 3.5 数据类型的定义和分类 在Rust…...

如何在vim中批量注释和取消注释

一、批量注释 首先在你需要注释的初始所在行在命令模式下输入CTRL v,然后按下HJKL来控制方向(不能使用键盘上的箭头方向键): 然后输入 shifti: 输入两个斜杠然后加exc就可以完成批量注释: 二、批量取消注…...

Centos7.9 安装Elasticsearch 8.15.1(图文教程)

本章教程,主要记录在Centos7.9 安装Elasticsearch 8.15.1的整个安装过程。 一、下载安装包 下载地址: https://www.elastic.co/cn/downloads/past-releases/elasticsearch-8-15-1 你可以通过手动下载然后上传到服务器,也可以直接使用在线下载的方式。 wget https://artifacts…...

哈希表-数据结构

一、哈希表基本概念 哈希表(也称为散列表)是根据键而直接访问在内存存储位置的数据结构,也就是说实际上是经过哈希函数进行映射,映射道表中一个位置来访问记录,这个存放记录的数组称为散列表。 哈希函数:就…...

指针之旅(4)—— 指针与函数:函数指针、转移表、回调函数

目录 1. 函数名的理解 1.1 “函数名”和“&函数名”的含义 1.2 函数(名)的数据类型 2. 函数指针(变量) 2.1 函数指针(变量)的创建格式 2.2 函数指针(变量)的使用格式 2.3 例子 判别 3. typedef 关键字 3.1 typedef的作用 3.2 typedef的运作逻辑 和 函数指针类型…...

打造线上+线下相结合的O2O平台预约上门服务小程序源码系统 带完整的安装代码包以及搭建部署教程

系统概述 本系统采用前后端分离的设计架构,前端以微信小程序为载体,提供直观、易用的用户界面;后端则采用稳定的服务器架构,确保数据处理的高效与安全。系统主要包括用户端、商户端和管理员端三大模块,通过API接口实现…...

python sys模块

在Python中,sys模块提供了访问和使用解释器的许多功能的方法,包括命令行参数、环境变量、路径管理、标准输入输出流等。sys模块是Python的标准库的一部分,不需要额外安装即可使用。 常用的sys模块功能 1. sys.argv sys.argv是一个包含命令…...

【Linux 报错】SSH服务器拒绝了密码。请再试一次。(xshell)

出现该错误 可能的原因: 你写入的登录密码错误了,错误原因有: 1、本来输入就错误了 2、创建用户时,只创建了用户名,但密码没有重新设置 3、多人使用同一台服务器时,该服务器管理员(本体&#x…...

云计算实训43——部署k8s基础环境、配置内核模块、基本组件安装

一、前期系统环境准备 1、关闭防火墙与selinux [rootk8s-master ~]# systemctl stop firewalld[rootk8s-master ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus…...

TAbleau 可视化 干货分享 | 简单三步助你打造完美仪表板

只需单击几下,你将能轻松创建美观、信息丰富的可视化效果、节省时间并推动业务向前发展! 借助精心设计的仪表板,分析师可以更好地理解复杂数据背后的信息,更有效地向他人分享你的见解,从而做出更明智的决策。 值得思考…...

JVM性能调优之5种垃圾收集器

JDK垃圾收集器 一、Serial GC垃圾收集器Serial GC的工作原理Serial GC的特点Serial GC的配置参数Serial GC的适用场景Serial GC的优缺点优点:缺点: Serial GC的总结 二、Parallel GC垃圾收集器Parallel GC的工作原理Parallel GC的特点Parallel GC的配置参…...

基于单片机的仔猪喂饲系统设计

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设…...

Helm Deploy Online Rancher v2.9.1

文章目录 准备安装查看下载 准备 $ kubectl get node NAME STATUS ROLES AGE VERSION kube-master01 Ready control-plane 19d v1.29.5 kube-node01 Ready <none> 19d v1.29.5 kube-node02 Ready <none&…...

【办公效率】Axure会议室预订小程序原型图,含PRD需求文档和竞品分析

作品说明 作品页数&#xff1a;共50页 兼容版本&#xff1a;Axure RP 8/9/10 应用领域&#xff1a;中小型企业的会议室在线预订 作品申明&#xff1a;页面内容仅用于功能演示&#xff0c;无实际功能 作品特色 本作品为会议室预订小程序原型图&#xff0c;定位于拥有中大型…...

论文解析一: SuperPoint 一种自监督网络框架,能够同时提取特征点的位置以及描述子

目录 SuperPoint&#xff1a;一种自监督网络框架&#xff0c;能够同时提取特征点的位置以及描述子1.特征点预训练2.自监督标签3.整体网络结构3.1 先对图像进行卷积3.2 特征点提取部分&#xff08;Interest Point Decoder&#xff09;3.3 特征描述子提取部分&#xff08;Descrip…...

【评估指标】Fβ-score

1. Fβ-score 概述 Fβ-score 是一种综合考量精确率&#xff08;precision&#xff09;和召回率&#xff08;recall&#xff09;的分类评估指标。其公式为&#xff1a; 1.1 Precision&#xff08;精确率&#xff09;&#xff1a;预测为正类的样本中&#xff0c;实际为正类的比…...

1963Springboot个性化音乐推荐管理系统idea开发mysql数据库web结构java编程计算机网页源码maven项目

博主介绍&#xff1a;专注于Java .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的可以…...

solidity从入门到精通(持续更新)

我一度觉得自己不知何时变成了一个浮躁的人&#xff0c;一度不想受外界干扰的我被干扰了&#xff0c;再无法平静的去看一本书&#xff0c;但我仍旧希望我能够克服这些&#xff0c;压抑着自己直到所有的冲动和奇怪的思想都无法再左右我行动。 自律会让你更加自律&#xff0c;放纵…...

UEFI入门(二):edk2项目编译流程

UEFI入门&#xff08;二&#xff09;&#xff1a;edk2项目编译流程 一、编译构建流程&#xff1a;1. 安装依赖工具2. 初始化构建环境3. 配置工具链和目标4. 定义平台配置5. 构建并编译 二、uefi-tools编译edk2实践&#xff1a;1. 克隆EDK2 项目2. 构建并编译 参考文章&#xff…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...