Where should I install C++ module interfaces units?

108 Views Asked by At

I'm using the newly added C++20 modules support in CMake. I'm using it to compile a library and installing it. Everything seems cool and good:

add_library(mylib)
target_sources(mylib PUBLIC FILE_SET CXX_MODULES FILES
    src/mymlib.cpp
)

# later, in my install rules:
include(GNUInstallDirs)

install(
    TARGETS mylib
    EXPORT mylib-targets

    RUNTIME #
    COMPONENT mylib-runtime
    DESTINATION "${CMAKE_INSTALL_BINDIR}"

    LIBRARY #
    COMPONENT mylib-runtime
    NAMELINK_COMPONENT mylib-development
    DESTINATION "${CMAKE_INSTALL_LIBDIR}"

    ARCHIVE #
    COMPONENT mylib-development
    DESTINATION "${CMAKE_INSTALL_LIBDIR}"

    INCLUDES #
    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"

    FILE_SET CXX_MODULES DESTINATION "cxx-modules"
)

There's a problem: you may notice I put "cxx-modules" hardcoded in the install command.

To use the platform's default install locations, I'm using GNUInstallDirs. However, there's no variable where it specifies where I should install my interface units.

I kinda used "cxx-modules" as a placeholder and it works, but I don't think that's the standard unix location to install interface units. What should I put there?

1

There are 1 best solutions below

1
starball On

At the time of this writing, I don't think there's any widely established convention on this yet.

libc++ case study

There was related discussion with libc++ and SG15. See this comment in a related LLVM issue ticket in December 2023, which summarizes the discussion that some libc++ people had with SG15, and giving some info on a new metadata file thing. It seems to have ended (for now) with libc++ 18 enabling opt-in to installation of their cppm file(s), with a default location. Quoting the release notes:

The .cppm files of experimental standard library modules can now be installed. By default, they are not installed. This can be enabled by configuring CMake with -DLIBCXX_INSTALL_MODULES=ON. The installation directory can be configured with the CMake option -DLIBCXX_INSTALL_MODULE_DIR=<path>. The default location is ${PREFIX}/share/libc++/v1.

There were other ideas in that issue ticket, here (next to their headers in /usr/include/c++/v1/ or /usr/include/c++/v1/modules/), here (/usr/modules/ as a strawman of what would lead to friction for downstream package maintainers), here (/usr/include/<target-triplet>/ a debian distro thing), here (/usr/lib/).

Related ISOCPP mailing list

  • Mark de Wever (a libc++ developer), started the discussion, proposing ${PREFIX}/share/c++/modules/<library>/ in July 2023.

  • Daniela Engert (one of the C++ committee members who is doing a lot of work and experimentation with C++ modules) replied that they tend to create a /modules/ sibling directory for libraries that already split /src/ and /include/, and otherwise put module files where headers are, but it's not clear to me how much this comment was about source layout and how much about installation layout.

  • Ben Boeckel, (one of the CMake maintainers), replied that they have an affinity toward ${PREFIX}/lib or somewhere close to the installed library('s binary) itself, since they're tied to compiled artifacts.

  • Boris Kolpackov (the build2 dev) replied that (pretty much the same as they gave when they initiated the above mentioned LLVM issue ticket) they suggest reusing the header installation location, since module interface units are similar to headers in their role, and it would allow reuse of existing machinery like the directory's existence itself, and header search logic in compilers.

  • Gaby (one of the Microsoft people working on modules and MSVC) replied that MSVC uses a sibling directory "modules/" next to include/, linking to an example at https://github.com/GabrielDosReis/cmake-for-modules/blob/main/CXXModuleExperimentalSupport.cmake. I have the same comment here as I had for Daniela's reply. The linked example doesn't seem to configure installation location- just source location.

  • Daniel Ruoso replied that they prefer something under libdir, such as $(libdir)/c++/modules/$(package)/.


Fun random fact, CMake has a CXX_MODULES_BMI install artifact option group, which surprises me, since I've heard people saying BMIs have no standard stability/compatibility guarantees (Ex. compatibility between BMIs generated by different minor versions of the same compiler, and that the binary format is compiler-flag-sensitive), and that they're not meant for distribution (Ex. here, here, here, here). Even just the module interface files would apparently need a metadata file to add compatibility info (source). Adding to the weirdness, if I understand this comment correctly, at least one of CMake's own maintainers discourages using the feature. The same maintainer also said it's not a focus of current module-support work in CMake here.