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 编译要接近半小时:偶 ...
随机推荐
- 【BZOJ1879】[SDOI2009]Bill的挑战(动态规划)
[BZOJ1879][SDOI2009]Bill的挑战(动态规划) 题面 BZOJ 洛谷 题解 本来还想着容斥来着,这个数据范围直接暴力就好.设\(f[i][S]\)表示当前填到了第\(i\)位,和\ ...
- 洛谷 P1407 [国家集训队]稳定婚姻 解题报告
P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...
- service的生命周期
Managing the Lifecycle of a Service service的生命周期,从它被创建开始,到它被销毁为止,可以有两条不同的路径: A started service 被开启的s ...
- (转)Java 中正确使用 hashCode 和 equals 方法
背景:最近在编写持久化对象时候遇到重写equals和hashCode方法的情况,对这两个方法的重写做一个总结. 链接:https://www.oschina.net/question/82993_75 ...
- mysql.user表中Host为%的含义
百度搜: MySQL之权限管理(mysql.user表详解) 连接:http://blog.csdn.net/zmx729618/article/details/78026497 mysql.user ...
- 02-css的选择器
css的选择器:1.基本选择器 2.高级选择器 基本选择器包含: 1.标签选择器 标签选择器可以选中所有的标签元素,比如div,ul,li ,p等等,不管标签藏的多深,都能选中,选中的是所有的,而不是 ...
- springboot静态资源处理
转:https://blog.csdn.net/catoop/article/details/50501706 Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConf ...
- Java 读取文件的内容
Java 读取文件的内容 1) CLASS_NAME: 换成自己真实的类名 2) /page/test.json: 换成自己真实的page 3) FileUtils: 来自于org.apache.co ...
- Tomcat的配置文件详解
Tomcat的配置文件详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Tomcat的配置文件 Tomcat的配置文件默认存放在$CATALINA_HOME/conf目录中, ...
- 函数和常用模块【day06】:xml模块(六)
本节内容 1.简述 2.xml格式 3.xml节点操作 4.创建新的xml文件 一.简述 xml是实现不同语言或者程序之间进行数据交换的协议,跟json差不多,但是json使用起来更简单,不过,古时候 ...