C++ Logo

sg15

Advanced search

Re: [Tooling] Tooling experience? (was Re: Proposed mission)

From: Boris Kolpackov <boris_at_[hidden]>
Date: Fri, 13 Apr 2018 12:18:54 +0200
Gabriel Dos Reis <gdr_at_[hidden]> writes:

> You, Boris, actually wen through the trouble of modularizing your tools
> (Modules TS semantics). I would like to hear from your concrete experience.

Sure. More specifically, we did the following:

1. Added support for Modules TS (GCC, Clang, and VC) to the build2 build
   system.

2. Modularized the build2 utility library (libbutl[1]; about 40 modules)
   as a first step in modularizing the entire toolchain. In the process
   we also created the std modules library (libstd-modules[2]) along the
   lines of the P0581R1[3] proposal and documented our experience in a
   set of modularization guidelines[4].

Now to the experience:

1. While support for Modules TS in a build system is sure complex, most
   of this complexity felt inherent rather than accidental.

   In particular, we were able to extract module dependency information
   without any support from the compilers by preprocessing the translation
   unit and then shallow-parsing the result to find module-related
   declarations. This shallow-parsing is possible thanks to all such
   declarations being top-level (which, I was told, was not by accident).
   See the code[5] if you are interested in details.

   Also, Modules TS fitted naturally into the overall "dependency extraction
   and compilation pipeline", which in build2 looks like this:

   1. Partially preprocess the translation unit (GCC's -fdirectives-only,
      Clang's -frewrite-includes; hopefully VC's new preprocessor will
      have something similar) and at the same time extract header
      dependency information (GCC/Clang's -M* options, VC's /showIncludes).

   2. Fully preprocess the translation unit and extract module dependency
      information. Here the user can also signal to the build system that
      no module declarations depend on the preprocessor (e.g., #ifdef'ed
      out, etc) in which case the full preprocessing is unnecessary (there
      is also a way to signal that the translation unit doesn't have any
      #include's to avoid partial preprocessing on step (1)).

   3. Compile the partially preprocessed translation unit. Interestingly,
      doing it this way (partially preprocessing all the translation units
      at the beginning and then compiling them can result[6] in faster
      overall builds).

   Also note that this pipeline is ready for distributed compilation where
   on step (3) we ship the partially preprocessed source and the imported
   BMIs to a remote host for compilation.

2. An attempt to modularize a real library that uses modern C++ didn't go
   smoothly. Currently, compiler support for Modules TS ranges from
   incomplete to buggy. I've only managed to build libbutl with modules
   enabled using Clang but had to hack both the compiler and libstdc++.
   The good news is there is a steady progress on the VC front with every
   release there are fewer and fewer remaining issues.

   We did, however, get an early glimpse at the kind of speedup we can
   expect -- in our case it was 3x compared to using headers.

If anyone is interested in any details, I would happy to elaborate.

[1] https://git.build2.org/cgit/libbutl/tree/
[2] https://git.build2.org/cgit/libstd-modules/tree/
[3] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0581r1.pdf
[4] https://build2.org/build2/doc/build2-build-system-manual.xhtml#cxx-modules-guidelines
[5] https://git.build2.org/cgit/build2/tree/build2/cc/parser.cxx
[6] https://build2.org/article/preprocess-compile-performance.xhtml

Boris

Received on 2018-04-13 12:19:02