This article duplicates the scope of other articles, specifically Unity build. Please discuss this issue and help introduce a summary style to the article. (April 2022)
This article may be too technical for most readers to understand. Please help improve it to make it understandable to non-experts, without removing the technical details. (March 2022) (Learn how and when to remove this template message)

Single compilation unit (SCU) is a computer programming technique for the C and C++ languages, which reduces compilation time for programs spanning multiple files. Specifically, it allows the compiler to keep data from shared header files, definitions and templates, so that it need not recreate them for each file. It is an instance of program optimization. The technique can be applied to an entire program or to some subset of source files; when applied to an entire program, it is also known as a unity build.[1]

Purpose

In the C/C++ compilation model (formally "translation environment"), individual .c/.cpp source files are preprocessed into translation units, which are then compiled separately by the compiler into multiple object (.o or .obj) files. These object files can then be linked together to create a single executable file or library. However, this leads to multiple passes being performed on common header files, and with C++, multiple template instantiations of the same templates in different translation units.

The single compilation unit technique uses pre-processor directives to "glue" different translation units together at compile time rather than at link time. This reduces the overall build time, due to eliminating the duplication, but increases the incremental build time (the time required after making a change to any single source file that is included in the SCU), due to requiring a full rebuild of the entire unit if any single input file changes.[2] Therefore, this technique is appropriate for a set of infrequently modified source files with significant overlap (many or expensive common headers or templates), or source files that frequently require recompilation together, such as due to all including a common header or template that changes frequently.[3]

Another disadvantage of SCU is that it is serial, compiling all included source files in sequence in one process, and thus cannot be parallelized, as can be done in separate compilation (via distcc or similar programs). Thus SCU requires explicit partitioning (manual partitioning or "sharding" into multiple units) to parallelize compilation.

SCU also allows an optimizing compiler to perform interprocedural optimization without requiring link-time optimization, therefore allowing optimizations such as inlining, and helps avoiding implicit code bloat due to exceptions, side effects, and register allocation. These optimizations are often not possible in many compilers, due to independent compilation, where optimization happens separately in each translation unit during compilation, but the "dumb linker" simply links object files, without performing any optimizations itself, and thus interprocedural optimization between translation units is not possible.

Example

For example, if you have the source files foo.cpp and bar.cpp, they can be placed in a Single Compilation Unit as follows:

#include "foo.cpp"
#include "bar.cpp"

Suppose foo.cpp and bar.cpp are:

//foo.cpp
#include <iostream> // A large, standard header
#include "bar.h"    // Declaration of function 'bar'

int main()          // Definition of function 'main'
{ 
  bar();
}
//bar.cpp
#include <iostream> // The same large, standard header

void bar()          // Definition of function 'bar'
{
  ...
}

Now the standard header file (iostream) is compiled only once, and function bar may be inlined into function main, despite being from another module.

See also

References

  1. ^ Developer, Unicorn (2017-12-25). "Speeding up the Build of C and C++ Projects". Medium. Retrieved 2022-03-16.
  2. ^ Krajewski, Marek (2019-01-31). Hands-On High Performance Programming with Qt 5: Build cross-platform applications using concurrency, parallel programming, and memory management. Packt Publishing Ltd. ISBN 978-1-78953-330-9.
  3. ^ Schach (1992-05-19). Practical Software Engineering. CRC Press. p. 183. ISBN 978-0-256-11454-6.