I would like to share a small prototype that may be relevant to the
ongoing discussion on C++20 module distribution.
Currently, `-lfoo` has no standardized mechanism for module interface
discovery. This prototype demonstrates an alternative approach: the
compiler can automatically extract `.cppm` source files from `.a`
archives, compile the BMI locally, and proceed without any changes to
the existing build pipeline.
Repository:
<
https://github.com/moonandlake123/autolink>
The key points:
- `.cppm` source files are packaged into `.a` archives alongside
object files at library build time.
- At consumption time, the compiler wrapper scans the archive,
extracts and compiles the module interface to BMI, then injects the
BMI path into the compiler command.
- No new file format, no BMI standardization, and no ABI changes are
required.
- Archives without `.cppm` files are passed through without
modification.
The prototype is verified on Clang 21 (Termux). GCC and MSVC
adaptations follow the same logic.
I welcome any feedback and would be grateful if this proves useful to
the work in SG15.
Have you seen this paper?
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3286r0.pdfIssues I see at a glance with the approach/implementation:
- assumes all files in a target are compiled with the same flags
- incremental compilation seems hampered due to direct
source-to-artifact requiring a full recompile on any source change
- compiles all sources in a single shot instead of separate compilation
(required for module-providing sources anyways without the frontend
becoming a build system itself)
- implementation assumes `.cppm`; there are no standard extensions for
module interface units
- unconditionally compiles discovered module interface units without
considering whether they're actually necessary or not
- assumes consumed targets have libraries (static or shared); there is a
desire to have binary-less "header-only"-like module libraries where
module initializer symbols are declared "unnecessary" so that
libraries can be shipped as just-module-interfaces
- doesn't consider that module interface units might need flags of their
own (e.g., `-I` flags for includes in the interface that consumers do
not need)
I think this might be useful for the "class assignment" level of usage
and genuinely be useful there (except for the flags needed by the
dependency), but is not usable as-is for tools like CMake, Meson, Bazel,
etc. So as long as the goal is to support that level of usage, this
could be a viable direction (modulo, of course, the BMIs being
compilable with the consumer's flags).
Thanks,
--Ben