Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 486|回复: 0

[默认分类] makefile中的wildcard和notdir和patsubst

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-3-29 09:46:30 | 显示全部楼层 |阅读模式
    转自:https://blog.csdn.net/srw11/article/details/7516712


    1、wildcard : 扩展通配符

    2、notdir : 去除路径


    3、patsubst :替换通配符



      
    例子:
      
    建立一个测试目录,在测试目录下建立一个名为sub的子目录
      
    $ mkdir test
      
    $ cd test
      
    $ mkdir sub
      

      
    在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件
      

      
    建立一个简单的Makefile
      
    src=$(wildcard *.c ./sub/*.c)
      
    dir=$(notdir $(src))
      
    obj=$(patsubst %.c,%.o,$(dir) )
      

      
    all:
      
    @echo $(src)
      
    @echo $(dir)
      
    @echo $(obj)
      
    @echo "end"
      

      
    执行结果分析:
      
    第一行输出:
      
    a.c b.c ./sub/sa.c ./sub/sb.c
      

      
    wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。
      

      
    第二行输出:
      
    a.c b.c sa.c sb.c
      
    notdir把展开的文件去除掉路径信息
      

      
    第三行输出:
      
    a.o b.o sa.o sb.o
      

      
    在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
      
    任何输出。
      
    或者可以使用
      
    obj=$(dir:%.c=%.o)
      
    效果也是一样的。
      

      
    这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
      
    它的标准格式是
      
    $(var:a=b) 或 ${var:a=b}
      
    它的含义是把变量var中的每一个值结尾用b替换掉a
      

      
    今天在研究makefile时在网上看到一篇文章,介绍了使用函数wildcard得到指定目录下所有的C语言源程序文件名的方法,这下好了,不用手工一个一个指定需要编译的.c文件了,方法如下:
      

      
    SRC = $(wildcard *.c)
      

      
    等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数,象这样:
      

      
    SRC = $(wildcard *.c) $(wildcard inc/*.c)
      

      
    也可以指定汇编源程序:
      
    ASRC = $(wildcard *.S)
      

      
    这样一来,makefile模板可修改的基本就是AVR名称和时钟频率了,其它的一般不用动了。
      

       
      

       
      

      PS:针对patsubst我们来好好聊一聊
      

      这是个模式替换函数
      
      
      格式:$(patsubst <pattern>,<replacement>,<text> )
    名称:模式字符串替换函数——patsubst。
    功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)
    返回:函数返回被替换过后的字符串。
      示例:
      $(patsubst %.c,%.o,x.c.c bar.c)
      把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”
       
      make中有个变量替换引用
       
      对于一个已经定义的变量,可以使用“替换引用”将其值中的后缀字符(串)使用指定的字符(字符串)替换。格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是,替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。“结尾”的含义是空格之前(变量值多个字之间使用空格分开)。而对于变量其它部分的“A”字符不进行替换。例如:
       
      foo := a.o b.o c.o
      bar := $(foo:.o=.c)
       
      在这个定义中,变量“bar”的值就为“a.c b.c c.c”。使用变量的替换引用将变量“foo”以空格分开的值中的所有的字的尾字符“o”替换为“c”,其他部分不变。如果在变量“foo”中如果存在“o.o”时,那么变量“bar”的值为“a.c b.c c.c o.c”而不是“a.c b.c c.c c.c”。
      它是patsubst的一个简化,那么到底是简化成了什么样子呢
       
      CROSS=
      CC=$(CROSS)gcc
      CFLAGS= -Wall  
      LDFLAGS=  
       
      PKG = src
       
      SRCS = $(wildcard $(PKG)/inc/*.c) $(wildcard $(PKG)/*.c)
      BOJS = $(patsubst %.c,%.o,$(SRCS))
      #BOJS = $(SRCS: .c = .o)
       
      #%.o:%.c
      # $(CC) -c $< $(CFLAGS) -o $@
       
      .PHONY:main
      main:$(BOJS)
      -$(CC) -o $@ $(CFLAGS) $^ $(LDFLAGS)
      -mv main ./myfile
      起初使用的是变量替换引用的方式,但是却始终不生成中间的.o文件,但是使用patsubst后,一切正常了,如果你知道为什么,请留言告诉我吧
      
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-25 21:45 , Processed in 0.366198 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表