[RFC] About the default location for std modules

I just had a chat with @mordante and we both agree on the following:

(1) Where should the *.cppm files live by default?

Right now, we install libc++ headers to <PREFIX>/include/c++/v1.

I think it would make the most sense to install .cppm files to a similar path like <PREFIX>/modules/c++/v1. This way, we would have something like:

<PREFIX>/modules/c++/v1/
                        std.cppm        // guaranteed to be there
                        std.compat.cppm // guaranteed to be there
                        [...]
                        std-variant.cppm // Implementation details, name not guaranteed and users don't rely on this.
                        std-foo.cppm     // We might want to move all of those to a subdirectory just for clarity.

I am not 100% attached to having the /v1/ subdirectory, however I feel pretty strongly that we should avoid putting std.cppm and all our other .cppm files at the top-level <PREFIX>/modules directory if we expect that subdirectory to be a fairly standard location to put modules files for various projects to avoid name collisions and for namespace hygene generally. This is really similar to how we wouldn’t want to throw our libc++ headers directly under /usr/include (and BTW the fact that the C library uses /usr/include directly is a common source of issues for vendors, at least over here).

(2) Where should the std.pcm live by default?

I am not sure we actually need to answer that question. Since the .pcm files are going to be built by users (or their build systems) for the foreseeable future, it doesn’t make sense to put those .pcm files relative to the compiler or relative to the libc++ installation (which could be relative to the compiler or relative to some SDK, depending). In fact, I would expect that in most cases users might not even have write access to those paths. Instead, I believe build systems should simply build the .pcm files from the .cppm files and put those .pcm files somewhere in their build directory. Build systems would then pass -fprebuilt-module-path=<PATH> to the compiler explicitly.

It would also be possible for Clang itself to go and do that work of building the .pcm files for your particular compiler invocation, however I would not try to encode whether and how Clang should do that if they decide to. At that point, Clang would be acting as a build system so as long as it knows where to find our .cppm files, everything should work.

This has been discussed a bunch, but whether BMIs will ever be portable is an open question, so I would recommend going for a simple solution that can unblock build systems sooner rather than later.

I think a lot of people also want to lower the barrier to users trying out C++ modules so they don’t have to build std.pcm & friends themselves. I completely agree that the user experience needs to be good, however I also want to exercise caution in shipping anything build-system specific. If we start shipping a .cmake file that allows building std.pcm more easily, we may open the floodgates for everyone to start contributing support for their favorite build system, and we should avoid that. IMO it would be acceptable to ship an “experimental” .cmake file at first to ease the integration for early adopters, but it should be made clear that that is not something that’s going to be stable and that we won’t add support for other build systems. This would basically be a way to ease the development and testing modules as we’re bootstrapping things, but nothing else. And once CMake officially supports building std.pcm from our .cppm files that .cmake file wouldn’t be necessary anymore and I would remove it.

Thoughts?

3 Likes