Browse Source

cmNinjaTargetGenerator: add flags for scanning based on the fileset type

Ben Boeckel 3 years ago
parent
commit
64c15ec018
2 changed files with 57 additions and 0 deletions
  1. 5 0
      Help/dev/experimental.rst
  2. 52 0
      Source/cmNinjaTargetGenerator.cxx

+ 5 - 0
Help/dev/experimental.rst

@@ -38,6 +38,11 @@ expected to process the translation unit, write preprocessor dependencies
 to the file specified by the ``<DEP_FILE>`` placeholder, and write module
 dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder.
 
+For tools which need to know the file set the source belongs to, the
+``CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_<FILE_SET_TYPE>`` flag may
+be provided so that different source types can be distinguished prior to
+scanning.
+
 The module dependencies should be written in the format described
 by the `P1689r4`_ paper.
 

+ 52 - 0
Source/cmNinjaTargetGenerator.cxx

@@ -21,6 +21,7 @@
 
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommandGenerator.h"
+#include "cmFileSet.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
@@ -28,6 +29,7 @@
 #include "cmLocalGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
 #include "cmNinjaNormalTargetGenerator.h"
 #include "cmNinjaUtilityTargetGenerator.h"
 #include "cmOutputConverter.h"
@@ -39,6 +41,7 @@
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmTarget.h"
 #include "cmValue.h"
 #include "cmake.h"
 
@@ -252,6 +255,55 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
       flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
   }
 
+  if (this->NeedCxxModuleSupport(language, config)) {
+    auto const& path = source->GetFullPath();
+    auto const* tgt = this->GeneratorTarget->Target;
+
+    std::string file_set_type;
+
+    for (auto const& name : tgt->GetAllFileSetNames()) {
+      auto const* file_set = tgt->GetFileSet(name);
+      if (!file_set) {
+        this->GetMakefile()->IssueMessage(
+          MessageType::INTERNAL_ERROR,
+          cmStrCat("Target `", tgt->GetName(),
+                   "` is tracked to have file set `", name,
+                   "`, but it was not found."));
+        continue;
+      }
+
+      auto fileEntries = file_set->CompileFileEntries();
+      auto directoryEntries = file_set->CompileDirectoryEntries();
+      auto directories = file_set->EvaluateDirectoryEntries(
+        directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
+
+      std::map<std::string, std::vector<std::string>> files;
+      for (auto const& entry : fileEntries) {
+        file_set->EvaluateFileEntry(directories, files, entry,
+                                    this->LocalGenerator, config,
+                                    this->GeneratorTarget);
+      }
+
+      for (auto const& it : files) {
+        for (auto const& filename : it.second) {
+          if (filename == path) {
+            file_set_type = file_set->GetType();
+            break;
+          }
+        }
+      }
+
+      if (!file_set_type.empty()) {
+        std::string source_type_var = cmStrCat(
+          "CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_", file_set_type);
+        cmMakefile* mf = this->GetMakefile();
+        if (cmValue source_type_flag = mf->GetDefinition(source_type_var)) {
+          this->LocalGenerator->AppendFlags(flags, *source_type_flag);
+        }
+      }
+    }
+  }
+
   return flags;
 }