C++ Logo

sg15

Advanced search

Re: [isocpp-sg15] [isocpp-core] [modules] wordings to allow build system to not always emit BMI for implementation partition units

From: Jason Merrill <jason_at_[hidden]>
Date: Wed, 14 Jan 2026 11:28:59 +0800
On Wed, Jan 14, 2026 at 10:09 AM Chuanqi Xu via SG15 <sg15_at_[hidden]>
wrote:

> > IMO, if you have a non-exported partition that you don't want exported,
> remove the partition name. It can (must) then be listed outside of a
> `CXX_MODULES` file set and won't make a BMI (whatever the costs may be).
> The standard already has a mechanism to do the "part of a module, but
> not making a BMI". Why do we need another subflavor of translation unit?
>

IIUC the issue is that if you have a TU that implements the interface of a
particular partition, and only needs to import that partition, removing the
partition name creates an interface dependency on the entire module,
resulting in unnecessary rebuilding if a different interface partition
changes.

Chuanqi proposes to handle this by giving the implementation unit its own
dummy partition name, and then wants a way to suppress BMI generation for
that dummy partition. But this seems a bit like piling kludge on kludge to
work around the lack of a way in the standard to specify an implementation
unit for a specific partition.

Alternatively, you could interpret this situation as a sign that you're
putting too much in a single module; if the interface of the partition is
so independent, perhaps it should be a separate module, e.g. mylib.net
instead of mylib:net.

This is the problem. It then requires the users to pay for the additional
> cost for generating BMIs. In some degree, it violates the zero-abstraction
> rule.
>
> I can understand that CMake didn’t optimize this due to human resources or
> what ever reasons. But I think we need to be on the same page that we
> should allow it.
>
> > Sure, if the build system can determine that an importable module unit
> isn't ever actually imported, then it can optimize away building the BMI.
> This seems like an "as-if" issue, unobservable by a conforming program.
> The standard doesn't say anything about build system artifacts.
> OTOH, BMI generation seems like a small overhead as a side effect of
> compilation, so it's unclear to me why avoiding it is a high priority.
>
> Thanks for clarification. I don’t think it is a high priority. But I do
> think it is a problem of CMake’s implementation. And a cmake dev says the
> root cause is the spec wording. That’s why I sent this.
>
> Thanks,
> Chuanqi
>
> ------------------------------------------------------------------
> From:core <core_at_[hidden]>
> Send Time:Wed, Jan 14, 2026, 03:03
> To:Chuanqi Xu<chuanqi.xcq_at_[hidden]>
> CC:Ben Boeckel<ben.boeckel_at_[hidden]>; core<core_at_[hidden]>;
> SG15<sg15_at_[hidden]>; Jens Maurer<jens.maurer_at_[hidden]>
> Subject:Re: [isocpp-core] [modules] wordings to allow build system to not
> always emit BMI for implementation partition units
>
> On Tue, Jan 13, 2026 at 11:19:32 +0800, Chuanqi Xu wrote:
> > As the author of CMake modules and who said the current wording has a
> > bug/defect, would you like to comment to explain why do you think the
> > current wording has a bug/defect for it?
> > CC Jens as the chair of CWG.
>
> This was not me (I am `mathstuf` on Reddit). It is, however, a fellow
> Kitwarean. He's not available right away, so I am speaking for myself
> here based on what he wrote.
>
> From Chuanqi's blog post:
> > However, in practice, there is a small issue for CMake users with this
> > approach. Currently, CMake requires all module implementation
> > partition units to be listed in CXX_MODULES_FILES, which causes CMake
> > to generate a BMI for each of them. This is a waste of time. In our
> > example, network.cpp, common.cpp, and util.cpp are designed not to be
> > imported by any other unit, a fact that the programmer can guarantee
> > and intends.
>
> From linked Reddit reply:
> > As discussed upstream, this is a standard bug and there's unlikely to
> > be any movement on it unless something changes in the standard.
> >
> > The standard has no way to advertise a "non-exporting" partition unit.
> > It is assumed all partition units export, thus all partition units
> > must generate a BMI. Notably, clang makes the same assumption whenever
> > it sees a .cppm extension.
> >
> > The MSVC behavior (absent /internalPartition) is simply broken and
> > non-conforming
>
> IMO, if you have a non-exported partition that you don't want exported,
> remove the partition name. It can (must) then be listed outside of a
> `CXX_MODULES` file set and won't make a BMI (whatever the costs may be).
> The standard already has a mechanism to do the "part of a module, but
> not making a BMI". Why do we need another subflavor of translation unit?
>
> From Chuanqi's Reddit reply:
> > For build system, my confusion part is, in bazel, it works fine if we
> > put the module unit in the `srcs` field instead of the
> > `module_interface` field. Given the support of modules in bazel
> > generally follows cmake, I don't understand why cmake can't make the
> > same behavior.
>
> CMake sees that the scanner says "makes a BMI named X", compares against
> its notes that it isn't expecting a BMI and assumes user error.
>
> --Ben
> _______________________________________________
> Core mailing list
> Core_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/core
> Link to this post: http://lists.isocpp.org/core/2026/01/19209.php
>
> _______________________________________________
> SG15 mailing list
> SG15_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>

Received on 2026-01-14 03:29:24