避免编译开销

时间:2013-12-11 08:08:11

标签: c++ compiler-construction spidermonkey

我正在研究SpiderMonkey项目,这是一个包含大量.h和.cpp文件的大型项目。尽管我知道我只更改了文件或两个文件,但每次我对项目进行更改时,我都必须运行make命令并再次编译整个项目以获取可执行文件./js

所以,我的问题是,是否有任何解决方案可以避免编译所有文件并仅编译特定文件以获取新的可执行文件./js

4 个答案:

答案 0 :(得分:3)

make的整个想法是仅重新构建需要重建项目的那些部分,通过文件修改日期和make可用的依赖关系信息来判断

如果你的项目需要很长时间才能重新编译,那么有三件事可能会受到责备:

  1. make可用的依赖关系信息不是最佳的,即make重新编译不需要重新编译的文件,因为它认为存在没有依赖关系的依赖关系。这将是Makefile的缺陷,即设计不良Makefile

  2. 有很多依赖项。实现文件包括许多标题,标题包括彼此等等。 - 最终只需要一点修改就需要重新编译大量翻译单元(通常在编辑头文件时)。这将是相关项目的架构缺陷,只能通过重大重构来解决。

  3. 该项目假定使用预编译头。这通常会产生一个非常大的头文件(或包含许多其他文件的头文件),然后以预处理的形式存储。包含此预处理标头是一个非常便宜的操作,但如果您的设置实际上不执行这种预处理(但包括单片头) ,编译时间可能会飙升。这将是您的设置的缺陷;查看可用的文档和设置。

  4. 哪一个负责您的具体问题?我说不出来,真的。 (我不知道Spidermonkey的第一件事。)

答案 1 :(得分:2)

鉴于SpiderMonkey是一个已建立的项目,可能是一些优秀的开发人员正在研究它,因此makefile基本上是合理的,只有相对较少的虚假依赖。如果这不成立,您可能需要查询SpiderMonkey社区,询问为什么对特定文件的修改会触发其他一些文件的重建,或者在代码级别上查看依赖文件的使用情况(也许通过有选择地删除#include来看看有什么破坏。

但是,您可能正在修改具有大量真正依赖关系的文件,例如由许多不同的翻译单元(直接或间接)包含的头文件。如果是这样的话,那么在没有重组代码的情况下你可以做的相对较少。可能有用的技术包括外部函数定义,前向声明标题(标准&#39; <iosfwd>),pImpl习语,使用虚拟接口,而不是完全模板快乐(作为定义)需要被客户端代码包含才能工作)。

答案 2 :(得分:1)

make实用程序具有 target dependency 的含义。只有在更改任何依赖时才会重建目标,否则会将其视为最新(简化说明)。以下Makefile将仅在更改任何目标文件时重建目标,并且仅在源/标题更改时才重建目标文件:

all: target

target: obj1.o obj2.o
    $(CC) -o $@ $^

obj1.o: obj1.c obj1.h
    $(CC) -o $@ -c $<

obj2.o: obj2.c obj2.h
    $(CC) -o $@ -c $<

话虽如此,您应该查看项目的Makefile并检查是否正确定义了依赖项。复杂的构建系统(例如autotools / automake)使用$(CC)-M或-MM来构建源的依赖项列表。

P.S。检查您的源/头文件日期是否正确而不是将来 - make通常会对该案例发出警告,因为它无法正确确定依赖项更改。这对于NFS文件尤其重要,NFS文件在一台计算机上编辑并在另一台计算机上编译。

答案 3 :(得分:0)

您可以尝试仅更改cpp文件,而不是h,因为cpp文件在项目中包含一次。 你也可以使用#pragma once指令,有些编译器可以加速编译。然而,您可以在公司中使用IncrediBuild工具。它在有IncrediBuild的所有计算机上分发编译。