C++ Logo

sg15

Advanced search

Re: [isocpp-sg15] Prototype: C++20 module interface discovery from static archives

From: Ben Boeckel <ben.boeckel_at_[hidden]>
Date: Fri, 12 Jun 2026 09:50:42 -0400
On Fri, Jun 12, 2026 at 11:38:56 +0000, moonlight via SG15 wrote:
> 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.pdf

Issues 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

Received on 2026-06-12 13:50:53