mikefile函数与实用模板

文章目录

  • 0.概述
  • 1.函数调用语法
  • 2.字符串处理函数
    • 2.1 subst(字符串替换函数)
    • 2.2 patsubst(模式字符串替换函数)
    • 2.3 strip(去空格函数)
    • 2.4 findstring(查找字符串函数)
    • 2.5 filter(过滤函数)
    • 2.6 filter-out(反过滤函数)
    • 2.7 sort(排序函数)
    • 2.8 word(取单词函数)
    • 2.9 wordlist(取单词串函数)
    • 2.10 words(单词个数统计函数)
    • 2.11 firstword(首单词函数——firstword)
  • 3.文件名操作函数
    • 3.1 dir(取目录函数)
    • 3.2 notdir(取文件函数)
    • 3.3 suffix(取後缀函数)
    • 3.4 basename(取前缀函数)
    • 3.5 addsuffix(加后缀函数)
    • 3.6 addprefix(加前缀函数)
    • 3.7 join(连接函数)
  • 4. 其他函数
    • 4. 1 foreach 函数(几乎是仿照for语句)
    • 4. 2 if 函数(类似make所支持的条件语句——ifeq)
    • 4. 3 call 函数(创建新的参数化的函数)
    • 4. 4 origin函数(变量是哪里来的)
    • 4. 5 shell函数(Shell的命令)
    • 4. 6 控制make的函数
  • 5. 补充
    • 5.1 wildcard
  • 6. 实用模板
    • 6.1 实例1
    • 6.2 实例2(生成多目标)

0.概述

在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能。

makefile详细消息见makefile经验总结。部分函数是工作中遇到的补充。

1.函数调用语法

函数调用,很像变量的使用,也是以 $ 来标识的,其语法如下:

$(<function> <arguments>)

或是:

${<function> <arguments>}

function 就是函数名,make支持的函数不多。 arguments 为函数的参数,参数间以逗号 , 分隔,而函数名和参数之间以“空格”分隔。函数调用以 $ 开头,以圆括号或花括号把函数名和参数括起。感觉很像一个变量,是不是?函数中的参数可以使用变量,为了风格的统一,函数和变量的括号最好一样。
示例:

comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))

在这个示例中, $(comma) 的值是一个逗号。 $(space) 使用了 $(empty) 定义了一个空格, $(foo) 的值是 a b c , $(bar) 的定义用,调用了函数 subst ,这是一个替换函数,这个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数是替换操作作用的字串。这个函数也就是把 $(foo) 中的空格替换成逗号,所以 $(bar) 的值是 a,b,c 。

2.字符串处理函数

2.1 subst(字符串替换函数)

在这里插入图片描述

2.2 patsubst(模式字符串替换函数)

在这里插入图片描述

2.3 strip(去空格函数)

在这里插入图片描述

2.4 findstring(查找字符串函数)

在这里插入图片描述

2.5 filter(过滤函数)

在这里插入图片描述

2.6 filter-out(反过滤函数)

在这里插入图片描述

2.7 sort(排序函数)

在这里插入图片描述

2.8 word(取单词函数)

在这里插入图片描述

2.9 wordlist(取单词串函数)

在这里插入图片描述

2.10 words(单词个数统计函数)

在这里插入图片描述

2.11 firstword(首单词函数——firstword)

在这里插入图片描述
以上,是所有的字符串操作函数,如果搭配混合使用,可以完成比较复杂的功能。这里,举一个现实中应用的例子。我们知道,make使用 VPATH 变量来指定“依赖文件”的搜索路径。于是,我们可以利用这个搜索路径来指定编译器对头文件的搜索路径参数 CFLAGS ,如:

override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))

如果我们的 $(VPATH) 值是 src:…/headers ,那么 ( p a t s u b s t (patsubst %,-I%, (patsubst(subst :, ,$(VPATH))) 将返回 -Isrc -I…/headers ,这正是cc或gcc搜索头文件路径的参数。

3.文件名操作函数

下面我们要介绍的函数主要是处理文件名的。每个函数的参数字符串都会被当做一个或是一系列的文件名来对待。

3.1 dir(取目录函数)

在这里插入图片描述

3.2 notdir(取文件函数)

在这里插入图片描述

3.3 suffix(取後缀函数)

在这里插入图片描述

3.4 basename(取前缀函数)

在这里插入图片描述

3.5 addsuffix(加后缀函数)

在这里插入图片描述

3.6 addprefix(加前缀函数)

在这里插入图片描述

3.7 join(连接函数)

在这里插入图片描述

4. 其他函数

4. 1 foreach 函数(几乎是仿照for语句)

在这里插入图片描述

4. 2 if 函数(类似make所支持的条件语句——ifeq)

在这里插入图片描述

4. 3 call 函数(创建新的参数化的函数)

在这里插入图片描述

4. 4 origin函数(变量是哪里来的)

在这里插入图片描述

4. 5 shell函数(Shell的命令)

在这里插入图片描述

4. 6 控制make的函数

在这里插入图片描述

5. 补充

5.1 wildcard

$(wildcard <PATTERN...>)

用于获取匹配该模式下的所有文件列表,<PATTERN…>参数若有多个则用空格分隔。若没有找到指定的匹配模式则返回为空。

在这里插入图片描述

6. 实用模板

基于工作经验编写的makefile 模板,基本满足日常需求。

6.1 实例1

#目标文件
TARGET = targe_bin
#目标路径
CUR_PATH = .
 
#获取所有c cpp文件
DIRS = $(shell find $(CUR_PATH) -maxdepth 10 -type d)
SRC = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
CSRC = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
CCSRC = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cc))
# 将所有.c,.cpp文件改为对应的.o文件
OBJS = $(patsubst %.cpp,${DIR_OBJ}/%.o,$(notdir ${SRC})) 
COBJS = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${CSRC})) 
CCOBJS = $(patsubst %.cc,${DIR_OBJ}/%.o,$(notdir ${CCSRC})) 

#确认.c文件路径
VPATH = $(DIR_SRC):$(XXX)
  1. 使用shell函数find 列出搜索路径下所有的文件列表
    在这里插入图片描述
  2. 通过foreach函数轮询find函数搜索结果,通过wildcard函数展开.cpp .c .cc文件,注意结果中包含路径
  3. 通过notdir函数去除第二步中的路径,再调用patsubst函数将.cc .c .cpp 文件转换为.o文件。

编译选项配置环节合库的链接。

#c语言编译选项
CFLAGS += -W -fPIC -DNONUTF8CONV -DELPP_NO_DEFAULT_LOG_FILE '-Wno-implicit-fallthrough' -Wfatal-errors
#cc cpp规则
CPPFLAGS += $(CFLAGS) -std=c++14 -fpermissive -no-pie

LIBS += -L./lib -Lxxx
LIBS +=  -lpthread -lxxx
 
INC += -I./ -I/xxx

目标生成

all: dir_check ${OBJS} ${COBJS} ${CCOBJS}
    $(CXX) $(CPPFLAGS) -g ${OBJS} ${COBJS} ${CCOBJS} -o ${BIN_TARGET} $(LIBS)
    
#$(CXX) $(CPPFLAGS) -g ${OBJS} ${COBJS} ${CCOBJS} -o ${BIN_TARGET} $(LIBS)
#编译所有源文件
${DIR_OBJ}/%.o:%.cpp
    $(CXX) $(CPPFLAGS) $(INC) -c $< -o $@ $(LIBS)
${DIR_OBJ}/%.o:%.cc
    $(CXX) $(CPPFLAGS) $(INC) -c $< -o $@ $(LIBS)
${DIR_OBJ}/%.o:%.c
    $(CC) $(CFLAGS) $(INC) -c $< -o $@ $(LIBS)
 
dir_check:
     -d ./obj || mkdir -p ./obj
 
.PHONY: clean
clean:
    rm -rf ${OBJS} ${COBJS} ${CCOBJS} $(BIN_TARGET)

通过自动化变量$@ $< 生成目标.o,通过目标.o生成bin文件。

6.2 实例2(生成多目标)

利用伪目标生成多目标,make一次生成多个。

# this is the build file for project 
# it is autogenerated by the xmake build system.
# do not edit by hand.

MXX=/usr/bin/gcc
AS=/usr/bin/gcc
CXX=/usr/bin/gcc
MM=/usr/bin/gcc
CC=/usr/bin/gcc

AR=/usr/bin/ar
SH=/usr/bin/g++
LD=/usr/bin/g++

example.out_CXXFLAGS=-m64 -g -xxx 
example.out_LDFLAGS=-m64 -g -Llib/linux -s -liclient -lcurl -lpthread -ldl

iclient_CXXFLAGS=-m64 -g -xxx
iclient_ARFLAGS=-cr

all:  iclient example.out 

#.PHONY: all  example.out iclient
.PHONY: all  example.out iclient

example.out: bin/example.out
bin/example.out: a.o b.o  c.o 
	 linking.release example.out
	 -p bin
	@$(LD) -o bin/example.out 
	
a.o: a.cpp
	 a.cpp
	 -p build
	@$(CXX) -c -g $(example.out_CXXFLAGS) -o a.o example/a.cpp > build/.build.log 2>&1

b.o: b.cpp
	 b.cpp
	 -p build
	@$(CXX) -c -g $(example.out_CXXFLAGS) -o b.o example/b.cpp > build/.build.log 2>&1
	
c.o: c.cpp
	 c.cpp
	 -p build
	@$(CXX) -c -g $(example.out_CXXFLAGS) -o c.o example/c.cpp > build/.build.log 2>&1



iclient: lib/linux/libiclient.a
lib/linux/libiclient.a: A.o B.o C.o 
	 linking.release libiclient.a
	 -p lib/linux
	@$(AR) $(iclient_ARFLAGS) lib/linux/libiclient.a A.o B.o C.o  > build/.build.log 2>&1

A.o: src/A.cpp
	 compiling.release A.cpp
	 -p build
	@$(CXX) -c -g $(iclient_CXXFLAGS) -o A.o A.cpp > build/.build.log 2>&1

B.o: src/B.cpp
	 compiling.release B.cpp
	 -p build
	@$(CXX) -c -g $(iclient_CXXFLAGS) -o B.o B.cpp > build/.build.log 2>&1
	
C.o: src/C.cpp
	 compiling.release C.cpp
	 -p build
	@$(CXX) -c -g $(iclient_CXXFLAGS) -o C.o C.cpp > build/.build.log 2>&1


clean:  clean_example.out clean_iclient

clean_example.out:  clean_iclient
	 -rf bin/example.out
	 -rf bin/example.out.sym
	 -rf a.o
	 -rf b.o
	 -rf c.o

clean_iclient: 
	 -rf lib/linux/libiclient.a
	 -rf lib/linux/iclient.sym
	 -rf A.o
	 -rf B.o
	 -rf C.o

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/613092.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Aigtek:电压放大器的选型标准是什么

选型电压放大器时&#xff0c;需要考虑多个因素&#xff0c;以确保选择适合特定应用需求的设备。电压放大器该怎么选择&#xff0c;下面安泰电子来介绍电压放大器常见的选型标准。 增益要求&#xff1a;首先需要确定所需的增益水平。根据输入信号的幅度和输出信号的要求&#x…

只需3步,使用Stable Diffusion无限生成AI数字人视频(附安装包)

基本方法 搞一张照片&#xff0c;搞一段语音&#xff0c;合成照片和语音&#xff0c;同时让照片中的人物动起来&#xff0c;特别是头、眼睛和嘴。 语音合成 语音合成的方法很多&#xff0c;也比较成熟了&#xff0c;大家可以选择自己方便的&#xff0c;直接录音也可以&#…

【ZZULI数据结构实验】压缩与解码的钥匙:赫夫曼编码应用

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

大文件传输的好帮手Libarchive:功能强大的开源归档文件处理库

在数字化时代&#xff0c;文件的存储和传输对于企业的日常运作至关重要。但是&#xff0c;服务器中的压缩文件往往无法直接查看或预览&#xff0c;这给用户带来了不便。为了解决这一问题&#xff0c;在线解压功能的开发变得尤为重要。接下来&#xff0c;小编将介绍一个能够实现…

了解集合与数据结构(java)

什么是数据结构? 数据结构就是 数据结构, 功能就是描述和组织数据 比如我有10万个QQ号, 我来组织, 有很多种组织方法, 比如链表, 树, 堆, 栈等等. 假如QQ号要查找数据, 有种数据结构查找数据速度很快, 我们就用它 加入QQ号要进行删除数据, 有种数据结构删除速度很快, 我们…

Spring Cloud Alibaba 网关 Gateway 集成(7)

项目的源码地址 Spring Cloud Alibaba 工程搭建&#xff08;1&#xff09; Spring Cloud Alibaba 工程搭建连接数据库&#xff08;2&#xff09; Spring Cloud Alibaba 集成 nacos 以及整合 Ribbon 与 Feign 实现负载调用&#xff08;3&#xff09; Spring Cloud Alibaba Ribbo…

【Web】CTFSHOW 月饼杯 题解(全)

目录 web1_此夜圆 web2_故人心 web3_莫负婵娟 web1_此夜圆 拿到源码&#xff0c;一眼字符串逃逸 本地测一测&#xff0c;成功弹出计算器 <?phpclass a {public $uname;public $password;public function __wakeup(){system(calc);} }function filter($string){retur…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第5章 安装SSH

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

【深度学习Labelme】使用Segment Anything Model (SAM)快速打标,labelme多边形转yolo txt框看看对不对

文章目录 windows安装环境打开labelme自动保存勾选上&#xff0c;保存图片数据不要勾选选SAM精准模型&#xff0c;然后打开图片路径&#xff0c;然后点击创建AI多边形&#xff1a;鼠标点击确认物体控制点&#xff0c;确认完成后&#xff0c;双击鼠标完成选取&#xff0c;并给上…

Django 静态文件管理与部署指南

title: Django 静态文件管理与部署指南 date: 2024/5/10 17:38:36 updated: 2024/5/10 17:38:36 categories: 后端开发 tags: WebOptCDN加速DjangoCompressWebpackStaticDeployCICD-ToolsSecStatic 第一章&#xff1a;介绍 Django 静态文件的概念和重要性 在 Web 开发中&a…

解读计数器算法:原理、Java实现与优劣分析

计数器算法的介绍 计数器算法的基本原理是通过一个计数器来记录事件的发生次数。每当一个特定的事件发生时&#xff0c;计数器的值就会增加一。当需要检查这个事件发生的次数时&#xff0c;只需要查看计数器的当前值即可。这种方法简单直观&#xff0c;易于理解和实现。 想象…

Docker + Django跨域解决方案

什么是Django Django 是一个开源的高级 Python Web 框架&#xff0c;它鼓励快速开发并遵循可重用和可维护的实践。Django 是在 MTV&#xff08;模型-模板-视图&#xff09;模式的基础上设计的&#xff0c;这个模式类似于但不同于 MVC&#xff08;模型-视图-控制器&#xff09;模…

雷森托尔环保科技有限公司见证2024杭州数字供应链装备展潮流

参展企业介绍 青岛雷森托尔环保科技有限公司创建于2018年&#xff0c;位于山东青岛&#xff0c;现注册资本3000万。公司主营生产模压木托盘、化工木托盘、大型设备木包装、出口木托盘、酒柜木酒架等&#xff0c;公司拥有技术人员6人&#xff0c;均为包装设计专业毕业&#xff0…

智慧公厕管理系统的四层架构:感知层、传输层、平台层和应用层

智慧公厕管理系统是一种利用先进技术实现智能化管理和优化厕所体验的创新解决方案。该系统采用复杂的架构&#xff0c;涵盖了多个应用子系统&#xff0c;致力于提高公厕的卫生状况、资源利用效率、安全性以及用户体验。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#…

element el-date-picker组件 输入输出格式为时间戳

<!-- 时间戳 --><el-date-pickerv-model"time"value-format"timestamp"type"date"placeholder"选择日期"/>// 把 value-format"timestamp" 加入 就可以实现时间戳格式

【数学】泰勒公式

目录 引言 一、泰勒公式 1.泰勒公式及推导 &#xff08;1&#xff09;推导 &#xff08;2&#xff09;公式 2.泰勒中值定理 &#xff08;1&#xff09;定理1&#xff08;佩亚诺余项&#xff09; &#xff08;2&#xff09;定理2&#xff08;拉格朗日余项&#xff09; …

前端动画requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画&#xff0c;并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数&#xff0c;该回调函数会在浏览器下一次重绘之前执行。 备注&#xff1a; 若你想在浏览器下次重绘…

GRU模块:nn.GRU层

摘要&#xff1a; 如果需要深入理解GRU的话&#xff0c;内部实现的详细代码和计算公式就比较重要&#xff0c;中间的一些过程及中间变量的意义需要详细关注。只有这样&#xff0c;才能准备把握这个模块的内涵和意义&#xff0c;设计初衷和使用方式等等。所以&#xff0c;仔细研…

实现流程化办公,可了解一下可视化报表开源

当前&#xff0c;实现流程化办公早已成为众多中小企业的发展目标和趋势。可以借助什么样的软件平台实现这一目标&#xff1f;低代码技术平台拥有可视化操作界面、够灵活、易维护等优势特点&#xff0c;在助力企业实现流程化办公、数字化转型方面具有重要的应用价值和推动作用。…

Selenium定位方法汇总及举例

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…