Linux Makefile 编译速度的优化【转】
转自: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 := foo
y := $(x) bar
x := 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)
:= 是立即变量赋值,在定义时值已经被确定。执行 make 时, x 的值已经是指定目录下的所有源文件了,所以尽管后面执行了三次 @echo $(x) ,但其实 Shell函数只调用了一次
= 是延时变量赋值,只有在这个变量被使用时才展开。执行 make 时, x 定义时其值并没有展开,所以后面执行了三次 @echo $(x) ,每次都调用了 Shell 函数,最终调用了三次 Shell 函数
通过以上分析过程,对于这两个运算符是如何影响编译速度的疑惑应该心里有底了。
总结
makefile 的解析分为两个阶段,第一阶段生成规则和依赖关系,第二阶段执行规则;只有立即展开的变量会在第一阶段计算,而延后展开的变量会在第二阶段计算。当使用‘=’赋值运算符对变量进行赋值,若变量定义中使用了函数,则包含在变量值中的函数总会在引用了该变量的规则的地方被执行,若 Makefile 中多处引用了该变量(不要忽略了隐晦规则中的引用),此时就需要考虑使用‘:=’赋值运算符,来减少变量的展开次数以及函数的调用次数,从而提高编译速度。
参考博文:http://blog.csdn.net/crylearner/article/details/17271195
---------------------
本文来自 Jerry_yl_ 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/QQ1452008/article/details/51851801?utm_source=copy
Linux Makefile 编译速度的优化【转】的更多相关文章
- linux makefile 编译多个.c文件 实例
本例由 main.c add.c sub.c add_sub.h 四个文件组成:编写Makefile执行程序 /******************************************* ...
- dWebpack编译速度优化实战
当你的应用的规模还很小时,你可能不会在乎Webpack的编译速度,无论使用3.X还是4.X版本,它都足够快,或者说至少没让你等得不耐烦.但随着业务的增多,嗖嗖嗖一下项目就有上百个组件了,也是件很简单的 ...
- [COCOS2DX]交叉编译实践+速度优化(vs2012修改win32代码+修改makefile+编译安卓项目包+部署安卓项目包到Eclipse+运行apk)
通过前面的部署过程可以知道cocos2dx的开发过程如下: 1.VS2012完成修改 2.因为指定了CPP文件位置,ndk可以通过jni方式完成C++文件的编译,运行以下命令完成proj.androi ...
- Linux系统——提高编译速度的方法
编译优化: 基本原则就是“以空间换时间” tmpfs: 解决IO瓶颈,充分利用本机内存资源 make -j: 充分利用本机计算资源 distcc: 利用多台计算机资源 ccache: 减少重复编译相同 ...
- Android Studio优化编译速度
随着Android Studio的不断完善,其安卓开发者阵营也基本从Eclipse转移到了Android Studio,毕竟Android Studio是谷歌亲力亲为开发的官方开发软件.不过其最重要的 ...
- 【Linux学习】 写一个简单的Makefile编译源码获取当前系统时间
打算学习一下Linux,这两天先看了一下gcc的简单用法以及makefile的写法,今天是周末,天气闷热超市,早晨突然发现住处的冰箱可以用了,于是先出去吃了点东西,然后去超市买了一坨冰棍,老冰棍居多, ...
- Linux 内核模块编译 Makefile
驱动编译分为静态编译和动态编译:静态编译即为将驱动直接编译进内核,动态编译即为将驱动编译成模块. 而动态编译又分为两种: a -- 内部编译 在内核源码目录内编译 b -- 外部编译 在内核源码的目录 ...
- 使用ant优化android项目编译速度,提高工作效率
1.Android项目编译周期长,编译项目命令取消困难 2.在进行Android项目的编译的同时,Eclipse锁定工作区不能进行修改操作 3.在只进行资源文件的修改时,Eclipse对资源文件的修改 ...
- 微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结
1.引言 岁月真是个养猪场,这几年,人胖了,微信代码也翻了. 记得 14 年转岗来微信时,用自己笔记本编译微信工程才十来分钟.如今用公司配的 17 年款 27-inch iMac 编译要接近半小时:偶 ...
随机推荐
- SVM学习笔记-线性支撑向量机
对于PLA算法来说,最终得到哪一条线是不一定的,取决于算法scan数据的过程. 从VC bound的角度来说,上述三条线的复杂度是一样的 Eout(w)≤Ein0+Ω(H)dvc= ...
- Twitter数据挖掘:如何使用Python分析大数据
我们可以创建变量来存放待拉取的微博数量(即count),以及待拉取的用户(即name).然后用这两个参数调用user_timeline()函数.下面是更新后的代码(注意,在代码的顶部应该保持认证和AP ...
- 【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)
[BZOJ1998][HNOI2010]物品调度(并查集,模拟) 题面 BZOJ,为啥这题都是权限题啊? 洛谷 题解 先不管\(0\)位置是个空,把它也看成一个箱子.那么最终的答案显然和置换循环节的个 ...
- [luogu3919]可持久化数组【主席树】
链接:https://www.luogu.org/problemnew/show/P3919 分析 很明显我们可以用主席树来维护,所谓主席树就是可持久化线段树,能够查询历史版本而且可以实现修改操作,反 ...
- ORMLite学习入门笔记
ORMLite学习入门笔记 使用原始的SQLiteHelper来操作维护数据库有点过于繁琐,重复工作量较大.所以会想到使用一个比较方便的ORM来维护我们本地的数据库,各位业界前辈都给我推荐了ORMLi ...
- [luoguU42591][小T的面试题]
luoguU42591 题意: n个不超过n的正整数中,其中有一个数出现了两次,其余的数都只出现了一次, 求这个出现两次的数. 思路: 这个题的亮点在于内存限制1MB.明显不能再用数组储存了,肯定是用 ...
- asp 调用 vb(activex dll) ,参数传递(传引用)需要注意
今天上午测试 vb 与 c(dll) 之间交互,传递参数的时候,没遇到什么太大的问题. 下午在asp中调用vb(activex dll)时, 在asp代码中传参数到 vb(dll)中时,遇到问题了. ...
- byteify
byteify函数 Python自带的Json库会把json文件load成Unicode对象. 如果想要变成str对象的话,就要自己去encode. def byteify(input): if is ...
- Makefile ------ $@ $^ %< 使用
一步一步理解 1.源程序的编译 在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们以一个实例来说明如何使用gcc编译器. 假设我们有下面一个非常简单的源程序(he ...
- nginx设置反向代理后端jenklins,页面上的js css文件无法加载
转载 2017年06月14日 22:36:59 8485 问题现象: nginx配置反向代理后,网页可以正常访问,但是页面上的js css文件无法加载,页面样式乱了. (1)nginx配置如下: (2 ...