google / prefab

Prefab is a tool for generating build system integrations for prebuilt C/C++ libraries.
https://google.github.io/prefab/
Apache License 2.0
210 stars 32 forks source link

[FR] Support c++ modules #180

Open yujincheng08 opened 7 months ago

yujincheng08 commented 7 months ago

Is your feature request related to a problem? Please describe. Since CMake 3.28, it supports c++ modules (see https://www.kitware.com/import-cmake-the-experiment-is-over/). We can set file set CXX_MODULES for a library so library or executable depend on it can use its module interface unit. However, prefab does not support c++ modules. The cmake package it generates does not set the CXX_MODULES file set.

Describe the solution you'd like Generate CXX_MODULES file set for the cmake package generated for a prefab package.

Describe alternatives you've considered In AGP, we can set headers directory in prefab.package, maybe it's better to add modules to set the directory for module interface unit.

Or we can use hardcode some extensions (e.g., .ixx, .cxx, .cppm) to generate the CXX_MODULES file set instead of add a new directory.

Additional context

"""target_sources($name INTERFACE FILE_SET CXX_MODULES BASE_DIRS "$includes" FILES
        "${files.joinToString(';')}")"""
DanAlbert commented 7 months ago

What's the actual shipped artifact here? The CMake article doesn't say.

https://stackoverflow.com/a/73601836 says that modules are not ready for binary distribution.

yujincheng08 commented 7 months ago

@DanAlbert Still .so or .a for a library. And the files in FILE_SET in type CXX_MODULES for cmake (module interface unit, files that declare export a module). You can verify this by performing a cmake install on a cmake project that uses c++ modules.

DanAlbert commented 7 months ago

But you're asking for a change in the distributed artifacts here. Which additional artifacts need to be distributed? As best as I can tell from the article you linked, it's source.

yujincheng08 commented 6 months ago

@DanAlbert well, we can distribute sources, in the case where the module interface unit and the module implement unit are in the same file. But we can also split them into different files. For example:

module interface unit foo.ixx:

export module foo;

export void test();
export struct Bar {
    Bar();
};

module implement unit foo.cxx:

module foo;
void test() {}
Bar::Bar() {}

then when we compile libfoo.so, we can only distribute foo.ixx, and when we place it into the include directory, prefab can distribute it. So actually we don't need to do extra support to support it. However, we can also scan public CXX_MODULES FILE_SET to identify which files are module interface units and need to be distributed.

DanAlbert commented 6 months ago

Ah, that was the missing piece. Thanks!

I guess the next bit of confusion is why the work you did in https://github.com/google/prefab/pull/181 (automatically filtering includes by extension to determine whether it's a module interface or a regular header) isn't something built in to CMake.