Explorar o código

ninja: add experimental infrastructure to generate gcc-format modmap files

Ben Boeckel %!s(int64=6) %!d(string=hai) anos
pai
achega
39cbbb59a5
Modificáronse 2 ficheiros con 44 adicións e 1 borrados
  1. 20 0
      Help/dev/experimental.rst
  2. 24 1
      Source/cmGlobalNinjaGenerator.cxx

+ 20 - 0
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
 the `cxx-modules-sandbox`_ test project, modified to set variables
 as above for their compiler.
 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=<MODULE_MAP_FILE>")
+
+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
 .. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html
 .. _`P1689r3`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1689r3.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
 .. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox

+ 24 - 1
Source/cmGlobalNinjaGenerator.cxx

@@ -2460,7 +2460,30 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
         // nothing to do.
         // nothing to do.
       } else {
       } else {
         std::stringstream mm;
         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 {
         } else {
           cmSystemTools::Error(
           cmSystemTools::Error(
             cmStrCat("-E cmake_ninja_dyndep does not understand the ",
             cmStrCat("-E cmake_ninja_dyndep does not understand the ",