转自:https://blog.csdn.net/QQ1452008/article/details/51851801

版权声明:本文为博主原创文章,未经博主允许不得转载。 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)
  1. := 是立即变量赋值,在定义时值已经被确定。执行 make 时, x 的值已经是指定目录下的所有源文件了,所以尽管后面执行了三次 @echo $(x) ,但其实 Shell函数只调用了一次

  2. = 是延时变量赋值,只有在这个变量被使用时才展开。执行 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 编译速度的优化【转】的更多相关文章

  1. linux makefile 编译多个.c文件 实例

    本例由 main.c  add.c sub.c add_sub.h 四个文件组成:编写Makefile执行程序 /******************************************* ...

  2. dWebpack编译速度优化实战

    当你的应用的规模还很小时,你可能不会在乎Webpack的编译速度,无论使用3.X还是4.X版本,它都足够快,或者说至少没让你等得不耐烦.但随着业务的增多,嗖嗖嗖一下项目就有上百个组件了,也是件很简单的 ...

  3. [COCOS2DX]交叉编译实践+速度优化(vs2012修改win32代码+修改makefile+编译安卓项目包+部署安卓项目包到Eclipse+运行apk)

    通过前面的部署过程可以知道cocos2dx的开发过程如下: 1.VS2012完成修改 2.因为指定了CPP文件位置,ndk可以通过jni方式完成C++文件的编译,运行以下命令完成proj.androi ...

  4. Linux系统——提高编译速度的方法

    编译优化: 基本原则就是“以空间换时间” tmpfs: 解决IO瓶颈,充分利用本机内存资源 make -j: 充分利用本机计算资源 distcc: 利用多台计算机资源 ccache: 减少重复编译相同 ...

  5. Android Studio优化编译速度

    随着Android Studio的不断完善,其安卓开发者阵营也基本从Eclipse转移到了Android Studio,毕竟Android Studio是谷歌亲力亲为开发的官方开发软件.不过其最重要的 ...

  6. 【Linux学习】 写一个简单的Makefile编译源码获取当前系统时间

    打算学习一下Linux,这两天先看了一下gcc的简单用法以及makefile的写法,今天是周末,天气闷热超市,早晨突然发现住处的冰箱可以用了,于是先出去吃了点东西,然后去超市买了一坨冰棍,老冰棍居多, ...

  7. Linux 内核模块编译 Makefile

    驱动编译分为静态编译和动态编译:静态编译即为将驱动直接编译进内核,动态编译即为将驱动编译成模块. 而动态编译又分为两种: a -- 内部编译 在内核源码目录内编译 b -- 外部编译 在内核源码的目录 ...

  8. 使用ant优化android项目编译速度,提高工作效率

    1.Android项目编译周期长,编译项目命令取消困难 2.在进行Android项目的编译的同时,Eclipse锁定工作区不能进行修改操作 3.在只进行资源文件的修改时,Eclipse对资源文件的修改 ...

  9. 微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结

    1.引言 岁月真是个养猪场,这几年,人胖了,微信代码也翻了. 记得 14 年转岗来微信时,用自己笔记本编译微信工程才十来分钟.如今用公司配的 17 年款 27-inch iMac 编译要接近半小时:偶 ...

随机推荐

  1. SVM学习笔记-线性支撑向量机

    对于PLA算法来说,最终得到哪一条线是不一定的,取决于算法scan数据的过程. 从VC bound的角度来说,上述三条线的复杂度是一样的 Eout(w)≤Ein0+Ω(H)dvc= ...

  2. Twitter数据挖掘:如何使用Python分析大数据

    我们可以创建变量来存放待拉取的微博数量(即count),以及待拉取的用户(即name).然后用这两个参数调用user_timeline()函数.下面是更新后的代码(注意,在代码的顶部应该保持认证和AP ...

  3. 【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)

    [BZOJ1998][HNOI2010]物品调度(并查集,模拟) 题面 BZOJ,为啥这题都是权限题啊? 洛谷 题解 先不管\(0\)位置是个空,把它也看成一个箱子.那么最终的答案显然和置换循环节的个 ...

  4. [luogu3919]可持久化数组【主席树】

    链接:https://www.luogu.org/problemnew/show/P3919 分析 很明显我们可以用主席树来维护,所谓主席树就是可持久化线段树,能够查询历史版本而且可以实现修改操作,反 ...

  5. ORMLite学习入门笔记

    ORMLite学习入门笔记 使用原始的SQLiteHelper来操作维护数据库有点过于繁琐,重复工作量较大.所以会想到使用一个比较方便的ORM来维护我们本地的数据库,各位业界前辈都给我推荐了ORMLi ...

  6. [luoguU42591][小T的面试题]

    luoguU42591 题意: n个不超过n的正整数中,其中有一个数出现了两次,其余的数都只出现了一次, 求这个出现两次的数. 思路: 这个题的亮点在于内存限制1MB.明显不能再用数组储存了,肯定是用 ...

  7. asp 调用 vb(activex dll) ,参数传递(传引用)需要注意

    今天上午测试 vb 与 c(dll) 之间交互,传递参数的时候,没遇到什么太大的问题. 下午在asp中调用vb(activex dll)时, 在asp代码中传参数到 vb(dll)中时,遇到问题了. ...

  8. byteify

    byteify函数 Python自带的Json库会把json文件load成Unicode对象. 如果想要变成str对象的话,就要自己去encode. def byteify(input): if is ...

  9. Makefile ------ $@ $^ %< 使用

    一步一步理解 1.源程序的编译 在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们以一个实例来说明如何使用gcc编译器. 假设我们有下面一个非常简单的源程序(he ...

  10. nginx设置反向代理后端jenklins,页面上的js css文件无法加载

    转载 2017年06月14日 22:36:59 8485 问题现象: nginx配置反向代理后,网页可以正常访问,但是页面上的js css文件无法加载,页面样式乱了. (1)nginx配置如下: (2 ...