This is already the status quo for static libraries on MSVC. And from what I can see there doesn’t seem to be a mechanism in MSVC’s static library toolchain that allows to restrict this, so Ben’s suggestion to enforce it on the CMake level instead may be the only option here.
Note that we need the mechanism regardless because we need to write install and export bits for these modules. While “can use from elsewhere” may be a possible IDE thing, writing out these files is certainly outside the scope.
@DanielaE Thank you for pointing me to the specification. I looked everywhere but there (I assumed it going to be too techincal). This example tied up the loose ends.
I got confused that partition implementation TUs are a thing.
While trying to understand modules. I watched this talk (entirely by coincidence - noticed a YouTube message a few days ago): https://www.youtube.com/watch?v=DJTEUFRslbI
So if I understand correctly we are supposed to compile std on our own for every project.
Will in that case make sense for the build system (in our case CMake) to provide standard facilities to automate this task? This is something I haven’t yet seen discussed anywhere else but in the talk in the link.
Yes. The idea is that we inspect information from the compiler about the standard library in use and make a target like CMake::CXX23 that provides the modules. It would be implicitly linked by anything using cxx_std_23. Note that adding flags like -std=c++23 not through a CMake-recognized standard-setting mechanism would likely not be something we notice.
The .cpp file is not a module file (i.e., it does not produce a BMI). It is instead an implementation unit of a module; it does not belong in CXX_MODULES filesets.
Wat?
Sorry, but a module TU with a partition name will always create a BMI because it is either a module interface partition (that contributes to the externally visible module interface) or an internal partition (that may or may not contribute to the externally reachable entitities of a module).
Oh, that : hid itself very well (I missed that . can be in the partition name too…). Anyways, MSVC does have an extension to allow such things (“implementation of partition” units; these don’t officially exist and should instead just use the module name only). Those files belong in the normal sources list.
But you’re right: module implementation units (the ones without a partition name) belong into the regular FILES section because they don’t create BMIs.
BTW: I’m experimenting with CMake 3.27 right now. Unfortunately it broke my (admittedly very brittle) “implementation” of ‘compiling header units with CMake workaround’ that worked in 3.26.
The issue @RobN created got closed. I got the impression that this is considered a problem of the build tools and not clang itself. So I would like to ask if there are any workarounds for this issue. Currently touching a single file can result in cascade of recompilations.
There’s some work that would be needed to do this, but it isn’t required to make modules work, hence it not being done right now. The basic requirement is that the collator has the compiler write the BMI to a temporary file and then communicate with a command in the same rule that does cmake -E copy_if_different to the real location. How exactly this gets communicated needs worked out though.
Are header units supported in cmake 3.27?
I am getting an error:
error: header file (aka ‘/usr/bin/…/lib/gcc/x86_64-linux-gnu/13/…/…/…/…/include/c++/13/vector’) cannot be imported because it is not known to be a header unit
p1689r5: initial support
This patch implements support for [P1689R5][] to communicate to a build
system the C++20 module dependencies to build systems so that they may
build `.gcm` files in the proper order.
Support is communicated through the following three new flags:
- `-fdeps-format=` specifies the format for the output. Currently named
`p1689r5`.
- `-fdeps-file=` specifies the path to the file to write the format to.
- `-fdeps-target=` specifies the `.o` that will be written for the TU
that is scanned. This is required so that the build system can
correlate the dependency output with the actual compilation that will
occur.