From 39cbbb59a52c63cd90eebaecea64fd42c3fad1d8 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 12 Mar 2019 15:36:12 -0400 Subject: ninja: add experimental infrastructure to generate gcc-format modmap files --- Help/dev/experimental.rst | 20 ++++++++++++++++++++ Source/cmGlobalNinjaGenerator.cxx | 25 ++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 4cf1c62..d019161 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -45,6 +45,26 @@ Compiler writers may try out their scanning functionality using the `cxx-modules-sandbox`_ test project, modified to set variables as above for their compiler. +For compilers that generate module maps, tell CMake as follows: + +.. code-block:: cmake + + set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG + "${compiler_flags_for_module_map} -fmodule-mapper=") + +Currently, the only supported format is ``gcc``. The format is described in +the GCC documentation, but the relevant section for the purposes of CMake is: + + A mapping file consisting of space-separated module-name, filename + pairs, one per line. Only the mappings for the direct imports and any + module export name need be provided. If other mappings are provided, + they override those stored in any imported CMI files. A repository + root may be specified in the mapping file by using ``$root`` as the + module name in the first active line. + + -- GCC module mapper documentation + .. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html .. _`P1689r3`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1689r3.html .. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 25d6a56..b7ca9b1 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2460,7 +2460,30 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // nothing to do. } else { std::stringstream mm; - if (false) { + if (arg_modmapfmt == "gcc") { + // Documented in GCC's documentation. The format is a series of lines + // with a module name and the associated filename separated by + // spaces. The first line may use `$root` as the module name to + // specify a "repository root". That is used to anchor any relative + // paths present in the file (CMake should never generate any). + + // Write the root directory to use for module paths. + mm << "$root .\n"; + + for (auto const& l : object.Provides) { + auto m = mod_files.find(l.LogicalName); + if (m != mod_files.end()) { + mm << l.LogicalName << " " << this->ConvertToNinjaPath(m->second) + << "\n"; + } + } + for (auto const& r : object.Requires) { + auto m = mod_files.find(r.LogicalName); + if (m != mod_files.end()) { + mm << r.LogicalName << " " << this->ConvertToNinjaPath(m->second) + << "\n"; + } + } } else { cmSystemTools::Error( cmStrCat("-E cmake_ninja_dyndep does not understand the ", -- cgit v0.12