头文件和 makefile 如何帮助 C++ 中的增量编译?
How do header files and makefiles help incremental compilation in c++?
我理解增量编译是什么:编译器只编译你编辑的代码而不是全部。但是,将代码分成 .h 和 .c/.cc 文件以及 C++ 中的 makefile 如何帮助增量编译呢?
Header 文件实际上对编译的增量适得其反。对任何 header 的任何更改都将导致所有包含 header 的源文件(甚至通过另一个 header 间接地)成为 re-compiled。但是 headers 使得在多个翻译单元中保持所有定义相同(正如语言所要求的)变得非常非常容易,因此它们的使用实际上是必要的。这种适得其反的生产力是 "include only what you need" 是要考虑的经验法则的原因。
有助于增量编译的只是每个翻译单元的定义更少。如果您将整个程序写在一个源文件中,那么对程序的任何一小部分进行任何微小的更改都会导致整个程序需要 re-compiled.
如果您改为将每个函数都写在一个单独的源文件中,那么对这些函数中的任何一个进行修改都将导致只需要重新编译那个微小的源文件,然后将其与未修改的先前编译的文件链接在一起object 文件。编译单个函数通常比编译整个程序更快。虽然,如果更改是例如函数的参数,那么调用该函数的所有内容 - 即它的依赖项 - 也必须重新编译(因此,这将是更改在 header 文件中的情况, 并且所有受抚养人都必须包括 header).
拥有多个源文件的另一个优点是它们可以独立编译,因此可以并行编译,考虑到当今的 multi-core 处理器,更不用说拥有无数行计算机系统的数据中心了。但也有缺点:Non-incremental 当有许多内联函数(特别是包括所有模板)时,从头开始编译通常更昂贵,需要为使用它们的每个单独的源文件重新编译。
诸如 make 和 ninja 之类的构建系统是一种工具,除了其他功能外,它们还跟踪以前编译的源文件,并在修改后决定哪些源文件需要 re-compilation。该决定通常基于源文件(以及所有包含的文件)与其编译的 object 文件相比的修改时间。
这一切都适用于使用 "dumb" non-incremental 编译器(大多数编译器)需要构建工具来过滤所需的 re-compilations 并且没有任何增量他们内部的逻辑。对于真正的增量编译器,构建系统甚至翻译单元划分可能都不是必需的。
我理解增量编译是什么:编译器只编译你编辑的代码而不是全部。但是,将代码分成 .h 和 .c/.cc 文件以及 C++ 中的 makefile 如何帮助增量编译呢?
Header 文件实际上对编译的增量适得其反。对任何 header 的任何更改都将导致所有包含 header 的源文件(甚至通过另一个 header 间接地)成为 re-compiled。但是 headers 使得在多个翻译单元中保持所有定义相同(正如语言所要求的)变得非常非常容易,因此它们的使用实际上是必要的。这种适得其反的生产力是 "include only what you need" 是要考虑的经验法则的原因。
有助于增量编译的只是每个翻译单元的定义更少。如果您将整个程序写在一个源文件中,那么对程序的任何一小部分进行任何微小的更改都会导致整个程序需要 re-compiled.
如果您改为将每个函数都写在一个单独的源文件中,那么对这些函数中的任何一个进行修改都将导致只需要重新编译那个微小的源文件,然后将其与未修改的先前编译的文件链接在一起object 文件。编译单个函数通常比编译整个程序更快。虽然,如果更改是例如函数的参数,那么调用该函数的所有内容 - 即它的依赖项 - 也必须重新编译(因此,这将是更改在 header 文件中的情况, 并且所有受抚养人都必须包括 header).
拥有多个源文件的另一个优点是它们可以独立编译,因此可以并行编译,考虑到当今的 multi-core 处理器,更不用说拥有无数行计算机系统的数据中心了。但也有缺点:Non-incremental 当有许多内联函数(特别是包括所有模板)时,从头开始编译通常更昂贵,需要为使用它们的每个单独的源文件重新编译。
诸如 make 和 ninja 之类的构建系统是一种工具,除了其他功能外,它们还跟踪以前编译的源文件,并在修改后决定哪些源文件需要 re-compilation。该决定通常基于源文件(以及所有包含的文件)与其编译的 object 文件相比的修改时间。
这一切都适用于使用 "dumb" non-incremental 编译器(大多数编译器)需要构建工具来过滤所需的 re-compilations 并且没有任何增量他们内部的逻辑。对于真正的增量编译器,构建系统甚至翻译单元划分可能都不是必需的。