I am in the process of converting my old code to something that is importable as c++-modules. The problem is that i would want it to still work and be easily maintained as the old header/source version. How do I do this (if possible).
Is it possible to create a module that export the content of a header? (Any other solution that lets you maintain old .cpp/.h files and module files is also accepted)
Toy example:
// In vector.h
template <typename T>
struct Vector {
T x, y;
}
// In .cppm
export module vector;
// #include "vector.h"
// Export struct/class Vector from header
What i have tried is just export Vector
in different versions, with and without templates etc.
Bonus question: Can you do this for the std lib? (for exmaple iostream, or string)
Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times. Macros, preprocessor directives, and non-exported names declared in a module aren't visible outside the module.
CMake currently does not support C++20 modules. See also the relevant issue in the CMake issue tracker. Note that supporting modules requires far more support from the build system than inserting a new compiler option.
Recently I created two answers first one regarding how to create module (in CLang) out of any old-style header. Second one regarding how to create modules out of STD headers.
Using these two answers now you can just code as before, in old .hpp
-based style. Then in usage code you can do following:
#if USE_MODULES
import std_mod; // Module created out of all STD headers.
import my_lib; // Module created out of my_lib.h.
#else
#include <iostream>
#include <vector>
// ... All other tons of STD headers ...
#include "my_lib.h"
#endif
int main() { use_my_lib(); }
Using headers as modules or as includes are totally interchangable, in both cases you'll have even macros, because CLang's header modules export macros as well.
Also you don't need any special syntax of creating my_lib
library. You don't need to use export
or module
keywords at all, you just code as in old-style C++ without modules and then your headers are easily converted to modules.
I did such thing in my quite huge C++ project. It was coded totally without modules and then automatically in my build system I converted all headers to modules, which greatly improved compilation speed. Of cause I implemented my own build system that is aware of includes and modules and automatically does conversion on flight without changing original files.
a) You want to keep your code (mostly) as-is, but put wrap it inside modules.
That would result in something similar to PCH, but standardized on a language level. Under the assumption that no code changes are neccessary, this has the following advantages:
The most simple way to achieve this is putting all your public headers in a single module:
// your_lib.cppm
module;
// global module fragment here
#include "your_header1.hpp"
#include "your_header2.hpp"
// ...
export module your_lib;
You should read about importable headers (the syntax already shown in the comments, e.g. import <iostream>
). As far as I know, what is an importable header is implementation defined. So in general, you would not have to use the global module fragment.
b) You want to modularize your code base, but allow others to still consume header files.
The only reason (which is a pretty good reason) to want something like this is to support the usage of your library for users that still use an older standard of C++20.
The solution you were hoping for is not really possible. Sorry. There is no way back from module to header. Everything internal to your library can be completely modularized. Then you have to make a decision. Keep the public interface as headers, or modularize it as well. In the first case, see a) on how you would consume your own public headers in your internal modules. In the second case you have to provide a second implementation of your interface as header files. As I said, you only choose b) to support older standard versions. So you'd also have to make sure to not to use any C++20 features in your (header based) public interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With