I will take examples from one of my own library I have converted to support both old style headers and modules.
This example is for a header only library, I will add an example of a library that is not header only when I have one.
Header only/module lib
Make export optional.
In my case I have defined a file with macros that adds export if the project is used with modules.
export.h
#pragma once
// Macros for handling compatability with/without modules
#ifdef matmath_use_modules
#ifndef matmath_export
#define matmath_export export
#endif
#else
#ifndef matmath_export
#define matmath_export
#endif
#endif
Then the headers for the library will be defined almost as usual, but with the minor tweak that the export macro is used instead of the export keyword for symbols that you want, and all includes are removed.
vec.h
// vec.h
#pragma once
#include "export.h"
#ifndef matmath_use_modules
#include <cmath>
#include <ostream>
#if __cplusplus >= 201103L
#include <tuple>
#endif
#include "pi.h"
#endif
matmath_export template <typename T>
class VecT {
public:
T x = 0, y = 0, z = 0;
constexpr VecT() = default;
...
};
Then you can use your header in a module of choice and activate the right macros.
vec.cppm
module;
#include <cmath>
#include <ostream>
import matmath.pi;
export module matmath.vec;
#define matmath_use_modules
#include "matmath/vec.h"
// If your file has a regular cpp-file you could include that
// here in the same fashion
// #include "path/to/vec.cpp"
And finally: When using the class you can choose to use the project through your module files, or through the header files (combining headers and modules for the lib yields a lot of pain though).
Enabling a small project to be built with and without modules
If you just want to build a small project with and without modules, you can just remove all export related statements and convert import statements to includes. This approach requires you to do changes to your code, or at least have a separate step that creates a copy of your code without the module related code. https://github.com/mls-m5/rym/blob/master/non-module-build.sh
import "header";
if"header"
is a standard library header or meets some implementation-defined criteria. – Cranerimport <iostream>;
in CLang for Windows and it issuederror: header file <iostream> (aka '<PATH_TO_MSVC>\include\iostream') cannot be imported because it is not known to be a header unit
. Using latest CLang and MSVC 2019 headers. – Gaylordgaylussac