【版权声明:转载请保留出处:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】

    这一节我们讲一下make的函数,在之前的章节已经讲到了几个函数:wildcard、patsubst、notdir、shell等。一般函数的调用格式例如以下:

$(funcname arguments)



$(funcname arguments)

当中funcname是须要调用函数的函数名称。应该是make内嵌函数;arguments是函数參数。參数和函数名之间使用空格切割,假设存在多个參数时,參数之间使用逗号“,”分开。

函数调用以“$”开头。使用成对的圆括号或花括号把函数名和參数括起,一般使用圆括号。

以下来看一下经常使用的一些函数:

1.    获取匹配模式文件名称函数—wildcard 。

使用方法:$(wildcard PATTERN)

该函数会列出当前文件夹下全部符合模式“PATTERN”格式的文件名称。

返回空格切割的、存在当前文件夹下的全部符合模式“PATTERN”的文件名称。

比如:

SRC_FILES = $(wildcard src/*.c)

返回src文件夹下全部.c文件列表。

2.    字符串替换函数—subst。

使用方法:$(subst FROM,TO,TEXT)

该函数把字串“TEXT”中的“FROM”字符替换为“TO”。返回替换后的新字符串。

3.    模式替换函数—patsubst。

使用方法:$(patsubst PATTERN,REPLACEMENT,TEXT)

该函数搜索“TEXT”中以空格分开的单词,将符合模式“TATTERN”替换为“REPLACEMENT” 。參数“PATTERN”中能够使用模式通配符“%”,来代表一个单词中的若干字符。假设參数“REPLACEMENT”中也包括一个“%” ,那么“REPLACEMENT”中的“%”将是“TATTERN”中的那个“%”所代表的字符串。

比如:

SRC_OBJ = $(patsubst %.c, %.o, $(SRC_FILES))

将SRC_FILES中全部.c文件替换为.o返回给变量SRC_OBJ。

此函数功能类似之前讲过的变量替换。http://blog.csdn.net/shallnet/article/details/37529935

变量替换格式是“$(var:a=b)”或“${var:a=b}”,其意思是。把变量“var”中全部以“a”字串“结尾”的“a”替换成“b”字串。

比如我们存在一个代表全部.c 文件的变量。定义为“src_files = a.c b.c c.c” 。

为了得到这些.c文件所相应的.o源文件。例如以下两种使用能够得到同一种结果::

$(objects:.c=.o)
$(patsubst %.c,%.o,$( src_files))

4.    过滤函数—filter。

使用方法:$(filter PATTERN…,TEXT)

该函数过滤掉字串“TEXT”中全部不符合模式“PATTERN”的单词,保留全部符合此模式的单词。能够使用多个模式。模式中一般须要包括模式字符“%” 。

存在多个模式时。模式表达式之间使用空格切割。返回空格切割的“TEXT”字串中全部符合模式“PATTERN”的字串。

5.    反过滤函数—filter-out。

使用方法:$(filter-out PATTERN...,TEXT)

和“filter”函数实现的功能相反。

过滤掉字串“TEXT”中全部符合模式“PATTERN” 的单词。 保留全部不符合此模式的单词。 能够有多个模式。存在多个模式时。模式表达式之间使用空格切割。

6.    取文件夹函数—dir。

使用方法:$(dir NAMES…)

从文件名称序列“NAMES…”中取出各个文件名称的文件夹部分。文件名称的文件夹部分就是包括在文件名称中的最后一个斜线( “/” ) (包括斜线)之前的部分。返回空格切割的文件名称序列“NAMES…”中每个文件的文件夹部分。假设文件名称中没有斜线,觉得此文件为当前文件夹( “./” )下的文件。

7.    取文件名称函数——notdir。

使用方法:$(notdir NAMES…)

从文件名称序列“NAMES…”中取出非文件夹部分。文件夹部分是指最后一个斜线( “/” ) (包含斜线)之前的部分。删除全部文件名称中的文件夹部分,仅仅保留非文件夹部分。

文件名称序列“NAMES…”中每个文件的非文件夹部分。

8.    取后缀函数—suffix。

使用方法:$(suffix NAMES…)

函数从文件名称序列“NAMES…”中取出各个文件名称的后缀。后缀是文件名称中最后一个以点“.”開始的(包括点号)部分。假设文件名称中不包括一个点号,则为空。 返回以空格切割的文件名称序列“NAMES…”中每个文件的后缀序列。

9.    取前缀函数—basename。

使用方法:$(basename NAMES…)

从文件名称序列“NAMES…”中取出各个文件名称的前缀部分(点号之后的部分) 。前缀部分指的是文件名称中最后一个点号之前的部分。

返回空格切割的文件名称序列“NAMES…”中各个文件的前缀序列。

假设文件没有前缀,则返回空字串。

这里只讲到一些经常使用的函数。另一些函数没有讲到,用到的时候能够去翻翻makefile手冊。



    通常情况下make在编译时会打印出当前正在运行的命令,当编译链接选项非常长时,会输出非常多东西在屏幕上,假设我 不想再屏幕上看到非常多东西。我们能够在命令前面加上@。这样命令就不会输出到屏幕了。我们这样尝试改动下:

# make
make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/ipc'
make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/ipc'
make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/tools'
make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/tools'
make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/main'
make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/main'
#

发现仅仅有进入文件夹和退出文件夹的显示。这样非常难知道眼下编译过程。事实上我们能够在规则命令处增加一行类似打印:

@echo "do something......"

这样能够输出眼下正在做的事。又不会输出正在运行命令。如今将规则改动下例如以下:

$(OBJDIR) :
>---@echo " MKDIR $(notdir $@)..."
>---@mkdir -p $@ ifneq ($(SRC_BIN),)
$(BINDIR)/$(SRC_BIN) : $(SRC_OBJ)
>---@echo " LINK $(notdir $@)..."
>---@$(CC) -o $@ $^ $(LDFLAGS)
endif ifneq ($(SRC_LIB),)
$(LIBDIR)/$(SRC_LIB) : $(SRC_OBJ)
>---@echo " ARCHIVE $(notdir $@)..."
>---@$(AR) rcs $@ $^
>---@echo " COPY $@ to $(SRC_BASE)/libs"
>---@cp $@ $(SRC_BASE)/libs
endif $(SRC_OBJ) : $(OBJDIR)/%.o : %.c
>---@echo " COMPILE $(notdir $<)..."
>---@$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

编译输出例如以下:

# make
make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/ipc'
COMPILE ipc.c...
ARCHIVE libipc.a...
COPY ../../build/unix_dbg/lib/libipc.a to ../../libs
make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/ipc'
make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/tools'
COMPILE base64.c...
COMPILE md5.c...
COMPILE tools.c...
ARCHIVE libtools.a...
COPY ../../build/unix_dbg/lib/libtools.a to ../../libs
make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/tools'
make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/main'
COMPILE main.c...
LINK target_bin...
make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/main'
#

当中文件夹切换的输出仍然非常多,我们能够将其关闭,这须要使用到make的參数,在make -C是指定--no-print-

directory參数。我们将顶层文件夹下Makefile规则改动例如以下:

$(BUILDDIR):
>---@echo " Create directory $@ ..."
>---mkdir -p $(BUILDDIR)/bin $(BUILDDIR)/lib $(MODULES):
>---@$(MAKE) -C $(DIR)/$@ MODULE=$@ --no-print-directory main:tools ipc clean :
>---@for subdir in $(MODULES); \
>---do $(MAKE) -C $(DIR)/$$subdir MODULE=$$subdir $@ --no-print-directory; \
>---done
编译输出:
# make
COMPILE ipc.c...
ARCHIVE libipc.a...
COPY ../../build/unix_dbg/lib/libipc.a to ../../libs
COMPILE base64.c...
COMPILE md5.c...
COMPILE tools.c...
ARCHIVE libtools.a...
COPY ../../build/unix_dbg/lib/libtools.a to ../../libs
COMPILE main.c...
LINK target_bin...
# make clean
rm -f ../../build/unix_dbg/obj/ipc/ipc.o ../../build/unix_dbg/lib/libipc.a
rm -f ../../build/unix_dbg/obj/main/main.o ../../build/unix_dbg/bin/target_bin
rm -f ../../build/unix_dbg/obj/tools/base64.o ../../build/unix_dbg/obj/tools/md5.o
../../build/unix_dbg/obj/tools/tools.o ../../build/unix_dbg/lib/libtools.a #

这样看上去输出清爽多了。事实上我们也能够使用make -s 来全面禁止命令的显示。

从头開始写项目Makefile(十):make内嵌函数及make命令显示的更多相关文章

  1. 从头開始写项目Makefile(五):嵌套运行

    [版权声明:转载请保留出处:blog.csdn.net/gentleliu.Mail:shallnew at 163 dot com] 在大一些的项目里面,全部源码不会仅仅放在同一个文件夹,一般各个功 ...

  2. 从头開始写项目Makefile(七):统一目标输出文件夹

    [版权声明:转载请保留出处:blog.csdn.net/gentleliu. Mail:shallnew at 163 dot com]     上一节我们把规则单独提取出来,方便了Makefile的 ...

  3. 从头开始写项目Makefile(十):make内嵌函数及make命令显示【转】

    转自:http://blog.csdn.net/shallnet/article/details/38314473#comments 版权声明:本文为博主原创文章,未经博主允许不得转载.如果您觉得文章 ...

  4. 从0開始写MyScrollView

    从0開始写MyScrollView 上篇文章对ScrollView的详细实现进行了分析.本文依据上篇分析的结果.自己动手写一个ScrollView. step1 尾随手指滑动,非常easy.重写2个函 ...

  5. [php learn] php 从头開始学习1

    前言:大概在2006年的时候,学习过一段时间的php.而且当时做了一个下载的站点,后来因为读研究生阶段用的是java.j2ee相关,所以php就搁浅掉了,php这些年也发生了非常大的变化,最大一个变化 ...

  6. Makefile所有内嵌函数

    一.文本处理函数以下是GNU make内嵌的文本(字符串)处理函数.1       $(subst FROM,TO,TEXT) 函数名称:字符串替换函数—subst. 函数功能:把字串“TEXT”中的 ...

  7. Makefile学习(二)条件判断和内嵌函数

    第七章:Makefile的条件执行 条件语句可是是两个不同的变量.或者变量和常量值的比较: 7.1例子: 对变量“CC”进行判断,其值如果是“gcc ”那么在程序连接时使用库“libgnu.so”或者 ...

  8. 从零開始写游戏引擎(一) - project创建以及文件夹设置还有版本号控制

    一句话提要 好的開始等于成功了一半. 创建文件夹结构 project文件夹下最好分为以下几个文件夹 Docs - 开发文档,设计文档 Assets - 角色,动作,模型和音效等 Source - 代码 ...

  9. SQL从头開始

    SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL) 查询和更新指令构成了 SQL 的 DML 部分: SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中 ...

随机推荐

  1. TeX中的引号(UVa272)

    问题: 在Tex中,做双引号的" `` ",右双引号是"  '' "(两个回车左边的).输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式. 样例输入: ...

  2. 【PAT】1014. 福尔摩斯的约会 (20)

    1014. 福尔摩斯的约会 (20) 大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hy ...

  3. PyQt5点击按钮产生新窗体

    import sys from PyQt5.QtWidgets import QApplication,QWidget from form1 import Ui_Form1 from form2 im ...

  4. Spark 源码解析:TaskScheduler的任务提交和task最佳位置算法

    上篇文章<  Spark 源码解析 : DAGScheduler中的DAG划分与提交 >介绍了DAGScheduler的Stage划分算法. 本文继续分析Stage被封装成TaskSet, ...

  5. python爬虫实战(五)--------智联招聘网

    前些天帮同事爬取一些智联招聘网上的关于数据分析的职位信息,他说要做一些数据分析看看,现在已经帮他爬完了.我本来想用Scrapy来爬的,但是不知道为什么爬取的数据和真实搜到的数据不太一样,比如:搜索到的 ...

  6. python-爬虫技能升级记录

    ====== python-爬虫技能升级记录 ====== ===== (一)感知爬虫及爬取流程 =====<code>从简单存取一个页面到 爬取到大量的定量数据,对技术要求更高,以百度百 ...

  7. redis_NoSql数据库四大分类

    前面简单介绍了什么是NoSql,以及NoSql的应用场景,今天简单来学习一下NoSql的分类 一.KV键值对 典型的介绍:新浪(BerkeleyDB+redis).美团(redis+tair).阿里, ...

  8. 安卓 onTouch OnTouchEvent onChick 顺序

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 分发触摸事件 -> 在 触摸 时候 -> 在触摸事件时候->在点击时候 ...

  9. [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)

    题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...

  10. 【期望DP】BZOJ3450- Tyvj1952 Easy

    ---恢复内容开始--- [题目大意] 有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连续a个comb就有a*a分,comb就是极大的连续o.求期望分数. [思路] 比之前的OS ...