Преглед изворни кода

Autogen: Add output caching GetExecutableTestOutput

This adds the cmQtAutoGenGlobalInitializer::GetExecutableTestOutput method
which caches the output of the called executable and returns the cached value
on any subsequent call.
Sebastian Holtermann пре 6 година
родитељ
комит
a4e01d6707
2 измењених фајлова са 70 додато и 0 уклоњено
  1. 64 0
      Source/cmQtAutoGenGlobalInitializer.cxx
  2. 6 0
      Source/cmQtAutoGenGlobalInitializer.h

+ 64 - 0
Source/cmQtAutoGenGlobalInitializer.cxx

@@ -6,10 +6,12 @@
 
 
 #include "cmAlgorithms.h"
 #include "cmAlgorithms.h"
 #include "cmCustomCommandLines.h"
 #include "cmCustomCommandLines.h"
+#include "cmDuration.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmMessageType.h"
+#include "cmProcessOutput.h"
 #include "cmState.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
@@ -183,6 +185,68 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
   }
   }
 }
 }
 
 
+bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput(
+  std::string const& generator, std::string const& executable,
+  std::string& error, std::string* output)
+{
+  // Check if we have cached output
+  {
+    auto it = this->ExecutableTestOutputs_.find(executable);
+    if (it != this->ExecutableTestOutputs_.end()) {
+      // Return output on demand
+      if (output != nullptr) {
+        *output = it->second;
+      }
+      return true;
+    }
+  }
+
+  // Check if the executable exists
+  if (!cmSystemTools::FileExists(executable, true)) {
+    error = "The \"";
+    error += generator;
+    error += "\" executable ";
+    error += cmQtAutoGen::Quoted(executable);
+    error += " does not exist.";
+    return false;
+  }
+
+  // Test the executable
+  std::string stdOut;
+  {
+    std::string stdErr;
+    std::vector<std::string> command;
+    command.push_back(executable);
+    command.emplace_back("-h");
+    int retVal = 0;
+    const bool runResult = cmSystemTools::RunSingleCommand(
+      command, &stdOut, &stdErr, &retVal, nullptr, cmSystemTools::OUTPUT_NONE,
+      cmDuration::zero(), cmProcessOutput::Auto);
+    if (!runResult) {
+      error = "Test run of \"";
+      error += generator;
+      error += "\" executable ";
+      error += cmQtAutoGen::Quoted(executable) + " failed.\n";
+      error += cmQtAutoGen::QuotedCommand(command);
+      error += "\n";
+      error += stdOut;
+      error += "\n";
+      error += stdErr;
+      return false;
+    }
+  }
+
+  // Return executable output on demand
+  if (output != nullptr) {
+    *output = stdOut;
+  }
+
+  // Register executable and output
+  this->ExecutableTestOutputs_.emplace(executable, std::move(stdOut));
+
+  return true;
+}
+
 bool cmQtAutoGenGlobalInitializer::generate()
 bool cmQtAutoGenGlobalInitializer::generate()
 {
 {
   return (InitializeCustomTargets() && SetupCustomTargets());
   return (InitializeCustomTargets() && SetupCustomTargets());

+ 6 - 0
Source/cmQtAutoGenGlobalInitializer.h

@@ -8,6 +8,7 @@
 #include <map>
 #include <map>
 #include <memory> // IWYU pragma: keep
 #include <memory> // IWYU pragma: keep
 #include <string>
 #include <string>
+#include <unordered_map>
 #include <vector>
 #include <vector>
 
 
 class cmLocalGenerator;
 class cmLocalGenerator;
@@ -38,10 +39,15 @@ private:
   void AddToGlobalAutoRcc(cmLocalGenerator* localGen,
   void AddToGlobalAutoRcc(cmLocalGenerator* localGen,
                           std::string const& targetName);
                           std::string const& targetName);
 
 
+  bool GetExecutableTestOutput(std::string const& generator,
+                               std::string const& executable,
+                               std::string& error, std::string* output);
+
 private:
 private:
   std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_;
   std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_;
   std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_;
   std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_;
   std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_;
   std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_;
+  std::unordered_map<std::string, std::string> ExecutableTestOutputs_;
 };
 };
 
 
 #endif
 #endif