博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux Makefile 编译速度的优化【转】
阅读量:5923 次
发布时间:2019-06-19

本文共 2001 字,大约阅读时间需要 6 分钟。

转自:

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/QQ1452008/article/details/51851801

前言

如何提高 Makefile 的编译速度呢?既然是提高,那肯定是对于大项目而言,因为小项目本身源文件不多,Makefile 优化与否,对于编译速度而言,影响并不大。当然对于那些追求速度达到极致的人而言,就另当别论了。废话不多说了,切入主题!

本博文会随着所遇见的Makefile编译速度有关的问题而持续更新。

1. 赋值运算符的影响

‘:=’ 和 ‘=’ 两个赋值运算符是如何影响编译速度的呢?这其中的奥妙就在于它们的本质含义,若是理解透彻了也就不会心存疑惑了,博主也是苦思了很久,并且搜索了很多网络资料,最后被该篇博文一语惊醒!

  • = 赋值运算符 - 递归展开式 - 延后展开
    “=”表示将整个 Makefile 展开后,再决定变量的值,即变量的值将会是整个Makefile中最后被递归展开所指定的值,而不管其引用的中间变量是在执行目标规则之前还是之后。

示例如下:

foo = $(bar)bar = $(ugh)ugh = $(Huh) all: @echo $(foo) Huh = AfterTarget

 

make之后其结果为 : AfterTarget其整个执行过程如下:    首先“$(foo)”被替换为“$(bar)”,    接下来 “$(bar)”被替换为“$(ugh)”, “$(ugh)”被替换为“$(Huh)”, 最后$(Huh)被替换为“AfterTarget”。 整个替换的过程是在执行“echo $(foo)”是进行的。

 

注意一句话:整个替换的过程是在执行“echo $(foo)”时进行的。

  • :=赋值运算符 - 直接展开式 - 立即展开
    “:=”表示变量的值决定于它在 Makefile 中的位置,而不是整个 Makefile 展开后的最终值。在使用该赋值运算符来定义变量时,变量值中对另外变量的引用或者函数的引用在定义时就被展开了,即定义时变量就已经是其表达式最终的值了。

示例如下:

x := fooy := $(x) barx := xyz

 

在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。


以上是这两个赋值运算符基本的说明,下面详细描述其是怎么影响编译速度的!

示例如下:

TmpDir = /Source  #此处随意定义了一个目录,                  #但切记在实际编写的 Makefile 中,不要在赋值语句后面写注释,                  #否则会把 /Source 到 # 之间的空格也算进去的。                  #在下面引用该变量的时候实际上‘/Source_’最后还多了一个空格                  #为了表示清楚,我用下划线表示空格,这样的目录肯定是不存在的 #以下语句调用了Shell函数,其结果是把指定目录下的所有源文件赋值给 x 变量, #两者取其一运行make #x := $(shell cd $(TmpDir); ls *.c) x = $(shell cd $(TmpDir); ls *.c) all: @echo $(x) @echo $(x) @echo $(x)

 

  1. := 是立即变量赋值,在定义时值已经被确定。执行 make 时, x 的值已经是指定目录下的所有源文件了,所以尽管后面执行了三次 @echo $(x) ,但其实 Shell函数只调用了一次

  2. = 是延时变量赋值,只有在这个变量被使用时才展开。执行 make 时, x 定义时其值并没有展开,所以后面执行了三次 @echo $(x) ,每次都调用了 Shell 函数,最终调用了三次 Shell 函数

通过以上分析过程,对于这两个运算符是如何影响编译速度的疑惑应该心里有底了。

  • 总结

    makefile 的解析分为两个阶段,第一阶段生成规则和依赖关系,第二阶段执行规则;只有立即展开的变量会在第一阶段计算,而延后展开的变量会在第二阶段计算。

    当使用‘=’赋值运算符对变量进行赋值,若变量定义中使用了函数,则包含在变量值中的函数总会在引用了该变量的规则的地方被执行,若 Makefile 中多处引用了该变量(不要忽略了隐晦规则中的引用),此时就需要考虑使用‘:=’赋值运算符,来减少变量的展开次数以及函数的调用次数,从而提高编译速度。

参考博文:

--------------------- 本文来自 Jerry_yl_ 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/QQ1452008/article/details/51851801?utm_source=copy 

你可能感兴趣的文章
JS 字符串全排列算法及内存溢出
查看>>
WPF:Animation动画--PropertyAnimation属性动画触发的方式
查看>>
JS数据类型& 判断
查看>>
前端面试题总结——HTML(持续更新中)
查看>>
脚本的加载和执行
查看>>
阿里云上到底能运行SAP哪些产品?
查看>>
如何在IDEA上运行Gradle工程
查看>>
iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 解析JSON
查看>>
iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 视图Nunjucks
查看>>
一种基于http协议的敏感数据传输方案
查看>>
入门爬虫的干货
查看>>
redux-promiseMiddleware的最佳实践
查看>>
【Docker实战之入门】Dockerfile详细分析:构建docker镜像(1)基础镜像centos7
查看>>
Java程序员修炼之道学习笔记(1)-简介
查看>>
如何利用WebSocket实现网页版聊天室
查看>>
网页转图片
查看>>
第二十五章:SpringBoot添加支持CORS跨域访问
查看>>
短链接系统的设计
查看>>
5.平凡之路-查询结果集简单处理
查看>>
【转载】一篇文章带你读懂Mysql和InnoDB
查看>>