Catch2 icon indicating copy to clipboard operation
Catch2 copied to clipboard

Add modules support

Open Benio101 opened this issue 2 years ago • 4 comments

Feature request

I do request adding modules support.

Description

Modules is a C++20 feature that fundamentally reduce recompilling time.

Compiler support

MSVC fully supports it since 16.8. Many other popular compilers, like GCC or clang, supports modules partially and shall support modules fully soon™.

Static linking alternative

There are significant differences between static linking and modules and modules should be available at least as an alternative.

Prerequisites

  • [ ] Restructure the code to get module partitions.
  • [ ] Xeither convert the existing code into conditional modules using __cpp_modules standard feature testing macro xor add module partition files along with the main module file that imports all partitions. In the last case, you should choose the modules extension name (eg /[ci]xx/ xor /c[px+]{2}m/).

Benio101 avatar Oct 08 '21 16:10 Benio101

Can modules export preprocessor definitions?

codeinred avatar Oct 11 '21 07:10 codeinred

So. The issues with compilation time are fixed by making Catch2 into a static/shared library (this has already been done in the development branch, which compiles significantly faster). Furthermore, there's no way to export macros with C++ modules, and given the heavy reliance of the library on Macros (as is appropriate for a testing framework), I believe this feature request is untenable: you'd still have to #include Catch2's test assertion macros, as well as other significant portions of the library.

I propose we close this issue.

codeinred avatar Oct 11 '21 10:10 codeinred

So, there are multiple parts to this.

  • Modules do not export macros. Only importable headers do, which are deeply in implementation-specified territory (only std headers are guaranteed to be importable, anything beyond that is dependent on the implementation). Even importable headers don't quite work for Catch2, because the definitions of macros are configurable by users, and importable headers isolate the sources from "external" macros.
  • Modules would likely still provide non-trivial speed ups for compilation, as they would greatly improve the performance of things like expression decomposition and internal stringification handling.
  • Supporting modules would require multiple parallel definitions and export models to be maintained, because the baseline language standard is C++14, not 20+, and I do not intend to move it all the way up any time soon.
  • Current module support of compilers is... lacking. Even the compiler that is currently the best at supporting modules, MSVC, contains whole bunches of bugs. GCC and Clang are outright broken. The less is said about common build systems, the better.

So all in all, if you want Catch2 to have improved performance of using modules, you should push implementations to allow importing header units of non-std headers, and then see what would need to be changed to make Catch2 importable. Modules are unlikely to happen.


For the speed up, you can also use precompiled headers right now. While they are not in an actual standard, and don't provide the special module linkage, they do provide very significant improvements to compilation times, in many cases equivalent with using proper modules.

horenmar avatar Oct 22 '21 14:10 horenmar

+1 for the support to C++20 modules, as a way to drastically reduce computational time, and maybe keep things on a single header file (I came to know now that v3 will use static lib... oh I just switched from googletest to catch2 because of that!). I know current C++20 modules status is poor, but we hope things improve somehow in next months/years... I mean, if this project could somehow publish a v3 C++14 version as planned, and another C++20 modules somehow without static linking stuff, that would be great! Just the opinion of an anonymous catch2 fan/user.

igormcoelho avatar May 10 '22 18:05 igormcoelho

Cmake support for cxx modules has landed outside of experimental, so it might be worth taking a look at how supporting cxx modules will look like. Disregarding the maintenance of standards < c++20, I have a suggestion about it:

  • main catch implementation and interface headers would be in modules This would require shifting internal macros such as the registrar to other formats, like using static_assert, traits, templates, etc.
  • macros such as SECTION, etc. Are still exported as headers that would be used in the global module section. This seems tobe the only way to support strimgification anyway right?

These are big daunting refactoring tasks so I don't see it coming any time soon and due to the size of refactoring would require dropping pre c++20 support. But I would say there are another few thing to be gained from this:

  • easier customization of catch2 registration and other behaviors
  • more navigable code. You wouldn't have to navigate a series of macros for each argument
  • more opportunities to enable catch2 extensions

LecrisUT avatar Oct 09 '23 22:10 LecrisUT

Closing because of fundamental issue with module-izing macro-heavy libraries and because such a change is well outside anything that could ship in v3. Perhaps when discussion a new major version this can be taken into consideration but as long as Catch is a macro-based library then modules are a tough fit.

ChrisThrasher avatar Jan 15 '24 22:01 ChrisThrasher

@igormcoelho +1 for the support to C++20 modules, as a way to drastically reduce computational time, and maybe keep things on a single header file (I came to know now that v3 will use static lib...

I would really like c++20 modules here, but I recognize that even c++20 did not manage to replace macros by some decent feature, and asking for modules in a macro world is unreasonable.

igormcoelho avatar Jan 16 '24 01:01 igormcoelho