最简makefile教程(二)

上篇讲解了makefile的基础知识,这篇介绍点更有意思的,能够大幅度提高编写编译指令效率的方法。

有这样一个需求,先将文件下的所有c文件编译,然后链接成可执行文件。

你不会要我写如下的代码吧:

app: a.o b.o c.o ....
    gcc -o app a.o b.o c.o
a.o : a.c
    gcc -c -o a.o a.c
b.o : b.c
    gcc -c -o b.o b.c
...

当然不是,至少gcc也支持通配符,这样就可以解决问题:gcc *.c -o app。我们先介绍makefile通配符匹配所有文件的函数--wildcard,用法如下:

查找文件夹下所有的c文件:

src = $(wildcard *c)
#然后我们可以这样:
app : $(src)
    gcc -o app $(src)

wildcard就是一个makefile函数,调用时的规则如下:

$(<function> <arguments> )
或是
${<function> <arguments>}

这里,<function>就是函数名,make支持的函数不多。<arguments>是函数的参数,参数间以逗号“,”分 隔,而函数名和参数之间以“空格”分隔。函数调用以“$”开头,以圆括号或花括号把函数名和参数括起。感觉很像一个变量,是不是?

为了更精准的把控整个项目,我们希望对每个c文件分开编译,然后链接,又该怎么办呢?

我们再介绍两个函数subst与patsubst,他们的作用都是字符串处理函数。

$(subst <from>,<to>,<text> )

名称:字符串替换函数——subst。

功能:把字串<text>中的<from>字符串替换成<to>。

返回:函数返回被替换过后的字符串。

示例:

x = $(subst .c,.o, a.c b.c )
将a.c b.c中的.c替换为.o,即x = a.o b.o

$(patsubst <pattern>,<replacement>,<text> )

名称:模式字符串替换函数——patsubst。

功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“/”来转义,以“/%”来表示真实含义的“%”字符)

返回:函数返回被替换过后的字符串。

示例:

x = $(patsubst %.c, %.o, a.c b.c )
将a.c b.c中的.c替换为.o,即x = a.o b.o

与上面不同的地方是:subst不是那么的智能,连空格也会替换,例如:

subst .c, .o, a.c 替换成了a. o,而patsubst则不会

subst .c,.o, a.cc 替换成了a.oc,而patsbust则不会替,保留a.cc

再介绍一种将变量中替换字符串的方法,例如:

x = a.c b.c 
y = $(x:.c=.cpp)   #y将变成a.cpp b.cpp注意=两边都不能有空格

y = $(x:.c=)       #y将变成a b,注意=两边都不能有空格,一般用这个得的可执行文件

 

虽然我们可以通过字符串替换函数把所有的.c文件全部替换为.o文件,例如:

objs = $(patsubst %.c, %.o, $(wildcard *.c)) 
#objs目前为a.o b.o c.o等等

但是是否所有的.o文件都要单独写编译指令呢?当然也不是,这里可以用makefile的模式规则,例如:

src = $(wildcard *.c)
objs = $(patsubst %.c, %.o, $(src)) 
app : $(objs)
	gcc  $^ -o $@       #$^表示所有的依赖文件,生成最终目标文件时,肯定要依赖所有的中间文件,$@表示目标文件
	
%.o : %.c    #模式规则,也可以写成.c.o:,不是.o.c:    
	gcc -c $< -o $@     #$<表示第一个依赖文件,因为在编译的时候,我们往往只编译一个c文件,其余可能都是.h文件,他不参与编译

为什么这里可以用模式规则呢,因为gcc在生成可执行目标文件的时候,其实隐含有一个编译为中间代码的步骤,例如:

objs = $(patsubst %.c, %.o, $(src)) 
app : $(objs)
    gcc -o app $(objs)    #这里会先调用cc -c -o x.o x.c生成中间文件

我们可以通过模式规则自定义执行命令来替换隐含的那个过程,达到想要的效果。

上面的代码中还遇到了$<,$^, $@等火星文,其实这些都是一些助记符,对编写简要的makefile帮助非常大。看看上面的注释应该很快能够理解。

看完本节之后,应该能写出非常简洁又高效的makefile文件。

 

欢迎加入QQ群 858791125 讨论skynet,游戏后台开发,lua脚本语言等问题。

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值