Makefile学习之路5——通过函数增强功能
通过函数能显著增强Makefile的功能。对于simple项目的Makefile,尽管使用了模式规则,但还是有一件比较麻烦的事情,就是要在Makefile中指明每一个项目源文件。下面介绍几个后期会使用到的函数,更多请参考《GUN Make》。
1.abspath函数
从命名就应该能够猜出它的作用。abspath函数用于将_name中的各路径名转化成绝对路径,并将转化后的结果返回。调用形式为:
$(abspath _name)
.PHONY: all
root :=$(abspath /uer/../lib)
all:
@echo $(root)

2.addprefix函数
addprefix函数用于给名字列表_name中的每一个名字增加前缀_prefix,并将增加了前缀的名字列表返回,调用形式为:
$(addprefix _prefix,_name)
.PHONY: all
without_dir=main.c foo.c
with_dir :=$(addprefix objs/,$(without_dir))
all:
@echo $(with_dir)

3.addsuffix函数
和前面addprefix刚好相反,addsuffix函数为_name增加后缀_suffix,调用形式为:
$(addsuffix _suffix,_name)
.PHONY: all
without_dir=main foo
with_dir :=$(addsuffix .c,$(without_dir))
all:
@echo $(with_dir)

4.filter函数
filter函数被用于从一个名字列表_text中根据模式_patterm得到满足需要的名字列表并返回,其形式是:
$(filter _pattern,_text)
.PHONY: all
sources =foo.o bar.c main.c hell.s
sources :=$(filter %.c %.s,$(sources))
all:
@echo $(sources)

5.eval函数
eval函数的存在使得Makefile具有动态语言的特征。eval函数使得make将再一次解析_text语句。eval返回空字符串,调用形式为:
$(eval _text)
.PHONY: all
sources =foo.o bar.c main.c hell.s
$(eval sources :=$(filter %.c %.s,$(sources)))
all:
@echo $(sources)

虽然它和上面第四个函数运行结果完全一样,但是在某些场合却必须用eval。可参考:http://bbs.chinaunix.net/thread-2321462-3-1.html
eval的二次展开,是递归的一种形式,因为有时候在Makefile的表达式中,最后得出来的可能还是Makefile的表达式而非真正我们想要传递的值,需要再展开Makefile的表达式得到最终的结果。
6.filter-out函数
该函数用于从名字列表_text中根据模式_pattern滤除一部分名字并将滤除后的列表返回,其形式为:
$(filter-out _pattern,_text)
.PHONY: all
objs =foo.o main.o main1.o main2.o
result :=$(filter-out main%.o,$(objs))
all:
@echo $(result)

7.notdir函数
该函数用来从路径_name中抽取文件名,并将文件名返回。其形式为:
$(notdir _name)
.PHONY: all
file_name :=$(notdir c/d/e/f/a.c q/w/e/r/b.c)
all:
@echo $(file_name)

8.patsubst函数
该函数用来将名字列表_text中符合_pattern模式的名字替换成_replacement,并将替换后的名字列表返回。其形式为:
$(patsubst _pattern,_replacement,_text)
.PHONY: all
mixed=foo.c bar.c main.o
objs :=$(patsubst %.c,%.o,$(mixed))
all:
@echo $(objs)

9.realpath函数
该函数用于获取_name所对应的真实路径名。其形式为:
$(realpath _name)
.PHONY: all
root :=$(realpath ./)
all:
@echo $(root)

10.strip函数
如果希望清除名字列表中的多余空格,strip函数是最佳选择,它将_string中的多余空格去除后返回。其形式为:
$(strip _string)
.PHONY: all
ori=foo.c main.c
res:=$(strip $(ori))
all:
@echo "$(ori)"
@echo "$(res)"

这里对echo命令做了一点变动,细心的人已经发现加了一个双引号,如果不加双引号,这里的两个输出将是相同的。
双引号用于保持引号内所有字符的字面值(回车和空格也不例外)。
11.wildcard函数
该函数是通配符函数,通过它可以得到当前工作目录中满足_pattern模式的文件或目录名列表。其形式为:
$(wildcard _pattern)
.PHONY:all
srcs=$(wildcard *.c)
all:
@echo $(srcs)

有了上面函数的基础之后,我们来看看之前的simple项目,对它进行改进:
之前的代码:
.PHONY: clean CC = gcc
RM = rm EXE =simple
OBJS =main.o foo.o $(EXE): $(OBJS)
$(CC) -o $@ $^
%.o : %.c
$(CC) -o $@ -c $^
clean:
$(RM) -rf $(EXE) $(OBJS)
还是要手动添加源文件,麻烦,运用函数之后,改进如下:
.PHONY: clean CC = gcc
RM = rm EXE =simple
SRCS =$(wildcard *.c)
OBJS =$(patsubst %.c, %.o, $(SRCS))
$(EXE): $(OBJS)
$(CC) -o $@ $^
%.o : %.c
$(CC) -o $@ -c $^
clean:
$(RM) -rf $(EXE) $(OBJS)

此时我们增加一个源文件,touch bar.c,看看我们的Makefile需不需要修改。

从结果看,不用修改Makefile就可以增加源文件了,同理,删除也一样,这样的Makefile具有更好的鲁棒性。
Makefile学习之路5——通过函数增强功能的更多相关文章
- Makefile学习之路6——让编译环境更加有序
在大多项目中都会合理设计目录结构来提高维护性,在编译一个项目时会产生大量中间文件,如果中间文件直接和源文件放在一起,就显得杂乱而不利于维护.在为现在这个complicated项目编写makefile之 ...
- IOS学习之路-- 指针&宏函数
如果*p被()包住,说明指针变量p将来指向的是函数 //声明一个指针变量 //int (*p)(int, int) = sum; int (*p)(int, int); p = sum; // 如果* ...
- Python3学习之路~3.1 函数基本语法及特性、返回值、参数、局部与全局变量
1 函数基本语法及特性 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 语法定义: d ...
- Makefile学习之路——4
变量的类别有递归扩展变量和简单扩展变量.只用一个“=”符号定义的变量被称为递归扩展变量.通过下面例子观察递归扩展变量的特点. .PHONY: all foo=$(bar) bar=$(ugh) ugh ...
- Makefile学习之路——2
让你的makefile更专业. 在上一个Makefile所在目录下通过touch命令创建一个clean文件,执行make clean,将发现make总是提示clean文件是最新的,而不是按我们期望的那 ...
- Makefile学习之路——3
特殊变量: 在Makefile中,有两个变量特殊变量会经常用到:MAKE和MAKECMDGOALS.MAKE变量表示的是当前处理Makefile的命令名是什么.当需要在Makefile中运行另一个Ma ...
- Makefile学习之路——1
编写makefile,不是一个猛子扎进去试着写一个规则并对之调试,而应该先采用面向依赖关系的思考方法勾勒出makefile要表达怎样的依赖关系,这一点尤为重要.通过不断地练习这种思考方法,才可能达到流 ...
- php学习之路:php在iconv功能 详细解释
iconv函数库可以完毕各种字符集间的转换,是php编程中必不可少的基础函数库. 使用方法例如以下: $string = "亲爱的朋友欢迎訪问胡文芳的博客.希望给您带来一点点的帮助!&quo ...
- Python3学习之路~0 目录
目录 Python3学习之路~2.1 列表.元组操作 Python3学习之路~2.2 简单的购物车程序 Python3学习之路~2.3 字符串操作 Python3学习之路~2.4 字典操作 Pytho ...
随机推荐
- leetcode笔记:First Bad Version
一. 题目描写叙述 You are a product manager and currently leading a team to develop a new product. Unfortuna ...
- NPOI导出Excel时出现错误“Maximum column number is 255”
此错误并不是NPOI的问题,而是Excel的问题,原因是Excel的最大列255,所以导出的列超过255时就会出现此问题 但Excel2007以上并没有此问题,因为2007以上的列已经增加到16384 ...
- 第一章:走近java-深入理解java虚拟机-读书总结
java技术体系: 1.java程序设计语言 2.硬件平台上的java虚拟机 3.class文件格式 4.java的API类库 5.第三方的类库 JDK: java语言,虚拟机,java API类库 ...
- kCGImagePropertyExifDictionary 引用错误
kCGImagePropertyExifDictionary 引用错误 使用 AVFoundation拍照 //获取图片 [outputImage captureStillImageAsynchron ...
- 系统学习NIO
概述 适用于有一定编程基础的朋友,想系统学习NIO这块知识的朋友.知识点大体分3块:1:>概念了解(各类IO) 2>NIO的核心(缓存区,通道等) 3>网络IO 详细 代码下载:ht ...
- 深入理解JavaScript系列(转载)
深入理解JavaScript系列 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaSc ...
- Android系统示例分析之AndroidBeamDemo
在这个示例工程中,只有一个Activity: public class Beam extends Activity implements CreateNdefMessageCallback, ...
- MySQL5.6 主从复制 ERROR 1776 (HY000): Parameters MASTER_LOG_FILE
主从都开启了gtid,在设置从库的时候遇到了问题 mysql> CHANGE MASTER TO MASTER_HOST=‘xxx’,MASTER_USER='replicant',MASTER ...
- 【LeetCode】111. Minimum Depth of Binary Tree (2 solutions)
Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum depth is the n ...
- 【转载】安装mysql8.0.11以及修改root密码、连接navicat for mysql。
1.1. 下载: 官网下载zip包,我下载的是64位的: 下载地址:https://dev.mysql.com/downloads/mysql/ 下载zip的包: 下载后解压:(解压在哪个盘都可以的) ...