In modern C++ there will be modules (C++20). Even std will be available as a module (C++23). This will likely bring down compile times massively. But so far the only compiler with support for this today is MSVC.
Did someone get around the modules-linearise-the-build-graph problem?
In the before times, people were enraged with C++ compile times and wanted a solution. Modules could have fixed that, thus people assumed modules would fix that.
Then modules were designed with the primary motive of removing preprocessor macros from the language, with reference to fortran's binary module description model. The one that turns the trivially parallel compilation model into a directed graph.
I'm under the impression that C++ modules as shipped require you to build dependencies before uses and the inevitable linearisation of the build graph is considered "probably fine, whatever". Compiling individual translation units gets somewhat faster as you don't need to parse the headers each time, but you can no longer build everything simultaneously.
Do modules actually make compilation appreciably faster in msvc?
Modules don't linearise the build graph. Any independent modules are compiled in parallel, but dependents will wait for these modules to be compiled.
In fact the problem is the other way round: header-translation unit compilation does a ton of unnecessary repetitive copy-pasting and parsing in the name of achieving embarrassingly parallel compilation. IMO modules help express build and API dependencies clearer, and even despite the so-called loss of parallelisation, build times with modules are generally an order of magnitude faster.
An extreme example is Vulkan-Hpp, which has a module interface file[1], and header files that exceed 150K lines of code, cumulatively. Using these headers means even a simple example takes something like 20+ seconds to compile every time. This is even worse when using complicated standard headers like `<algorithm>`, `<functional>`, `<ranges>`, etc.
On the other hand, using the module, the compile only takes as long the first time, and every subsequent compile is lightning-quick.
It seems we're in agreement on the mechanism of modules. Thank you for the example - one really large header-only library would seem to be the ideal use case for precompiled headers. Sorry, modules.
There are of course alternatives to header only libraries so there's a sense in which this is a solution to a problem that didn't need to exist in the first place.
But yes, header only libraries are an important solution to the problem of cmake, and modules can patch around the compile time implications of header only libraries, so that's sort of all good.
With headers, every translation unit is some (probably large) amount of text spliced together then fed into the compiler front end. You parse <vector> and <string> over and over again. If headers are big or templates many, the time per translation unit get rather high.
With modules, as of the last time I looked, in order to compile some file, you must first compile the files it depends on, at least far enough to create a module file which is then depended on. Compiling a single translation unit with a bunch of already-existing module files should be faster than the equivalent with a lot of header files as you don't need to repeat the parsing.
This makes the individual compilations cheaper (win) but replaces independent work with a dependency graph traversal (loss).
It's totally obvious from the outside that the right solution is a compiler daemon. Integrate the build system with the compiler, persist state between separate file compilations. The C/C++ world really likes the independent batch compiler scheduled by cmake approach though so that arbitrarily constrains their design space.
It's fascinating that tooling choices from the early days (notably separate compilation is forced by insufficient memory) combined with the division of responsibility between compiler tooling vendors and the standards committee forces this sort of design.
All 3 major compilers offer the std module in C++20 as an extension, at least I remember an issue where it was discussed and agreed uppon by all. I don't actually know if it was actually implemented (yet?).
In the before times, people were enraged with C++ compile times and wanted a solution. Modules could have fixed that, thus people assumed modules would fix that.
Then modules were designed with the primary motive of removing preprocessor macros from the language, with reference to fortran's binary module description model. The one that turns the trivially parallel compilation model into a directed graph.
I'm under the impression that C++ modules as shipped require you to build dependencies before uses and the inevitable linearisation of the build graph is considered "probably fine, whatever". Compiling individual translation units gets somewhat faster as you don't need to parse the headers each time, but you can no longer build everything simultaneously.
Do modules actually make compilation appreciably faster in msvc?