Ver código fonte

server-mode: Add command to retrieve build system files

Add a command to retrieve files that are input to cmake itself.
Tobias Hunger 9 anos atrás
pai
commit
84553a6e70

+ 41 - 0
Help/manual/cmake-server.7.rst

@@ -558,3 +558,44 @@ listed by default.
 Finally you can limit the target types that are going to be listed. This is
 done by providing a list of target types as an array of strings to the
 "targetTypes" key.
+
+
+Type "cmakeInputs"
+^^^^^^^^^^^^^^^^^^
+
+The "cmakeInputs" requests will report files used by CMake as part
+of the build system itself.
+
+This request is only available after a project was successfully
+"configure"d.
+
+Example::
+
+  [== CMake Server ==[
+  {"type":"cmakeInputs"}
+  ]== CMake Server ==]
+
+CMake will reply with the following information::
+
+  [== CMake Server ==[
+  {"buildFiles":
+    [
+      {"isCMake":true,"isTemporary":false,"sources":["/usr/lib/cmake/...", ... ]},
+      {"isCMake":false,"isTemporary":false,"sources":["CMakeLists.txt", ...]},
+      {"isCMake":false,"isTemporary":true,"sources":["/tmp/build/CMakeFiles/...", ...]}
+    ],
+    "cmakeRootDirectory":"/usr/lib/cmake",
+    "sourceDirectory":"/home/code/src/cmake",
+    "cookie":"",
+    "inReplyTo":"cmakeInputs",
+    "type":"reply"
+  }
+  ]== CMake Server ==]
+
+All file names are either relative to the top level source directory or
+absolute.
+
+The list of files which "isCMake" set to true are part of the cmake installation.
+
+The list of files witch "isTemporary" set to true are part of the build directory
+and will not survive the build directory getting cleaned out.

+ 5 - 0
Source/cmServerDictionary.h

@@ -6,6 +6,7 @@
 
 // Vocabulary:
 
+static const std::string kCMAKE_INPUTS_TYPE = "cmakeInputs";
 static const std::string kCODE_MODEL_TYPE = "codemodel";
 static const std::string kCOMPUTE_TYPE = "compute";
 static const std::string kCONFIGURE_TYPE = "configure";
@@ -20,9 +21,11 @@ static const std::string kSIGNAL_TYPE = "signal";
 
 static const std::string kARTIFACTS_KEY = "artifacts";
 static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
+static const std::string kBUILD_FILES_KEY = "buildFiles";
 static const std::string kCACHE_ARGUMENTS_KEY = "cacheArguments";
 static const std::string kCAPABILITIES_KEY = "capabilities";
 static const std::string kCHECK_SYSTEM_VARS_KEY = "checkSystemVars";
+static const std::string kCMAKE_ROOT_DIRECTORY_KEY = "cmakeRootDirectory";
 static const std::string kCOMPILE_FLAGS_KEY = "compileFlags";
 static const std::string kCONFIGURATIONS_KEY = "configurations";
 static const std::string kCOOKIE_KEY = "cookie";
@@ -35,9 +38,11 @@ static const std::string kFRAMEWORK_PATH_KEY = "frameworkPath";
 static const std::string kFULL_NAME_KEY = "fullName";
 static const std::string kGENERATOR_KEY = "generator";
 static const std::string kINCLUDE_PATH_KEY = "includePath";
+static const std::string kIS_CMAKE_KEY = "isCMake";
 static const std::string kIS_EXPERIMENTAL_KEY = "isExperimental";
 static const std::string kIS_GENERATED_KEY = "isGenerated";
 static const std::string kIS_SYSTEM_KEY = "isSystem";
+static const std::string kIS_TEMPORARY_KEY = "isTemporary";
 static const std::string kLANGUAGE_KEY = "language";
 static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage";
 static const std::string kLINK_FLAGS_KEY = "linkFlags";

+ 97 - 2
Source/cmServerProtocol.cxx

@@ -5,6 +5,7 @@
 #include "cmExternalMakefileProjectGenerator.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
+#include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmServer.h"
@@ -61,6 +62,48 @@ static Json::Value fromStringList(const T& in)
   return result;
 }
 
+static void getCMakeInputs(const cmGlobalGenerator* gg,
+                           const std::string& sourceDir,
+                           const std::string& buildDir,
+                           std::vector<std::string>* internalFiles,
+                           std::vector<std::string>* explicitFiles,
+                           std::vector<std::string>* tmpFiles)
+{
+  const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
+  const std::vector<cmMakefile*> makefiles = gg->GetMakefiles();
+  for (auto it = makefiles.begin(); it != makefiles.end(); ++it) {
+    const std::vector<std::string> listFiles = (*it)->GetListFiles();
+
+    for (auto jt = listFiles.begin(); jt != listFiles.end(); ++jt) {
+
+      const std::string startOfFile = jt->substr(0, cmakeRootDir.size());
+      const bool isInternal = (startOfFile == cmakeRootDir);
+      const bool isTemporary = !isInternal && (jt->find(buildDir + '/') == 0);
+
+      std::string toAdd = *jt;
+      if (!sourceDir.empty()) {
+        const std::string& relative =
+          cmSystemTools::RelativePath(sourceDir.c_str(), jt->c_str());
+        if (toAdd.size() > relative.size())
+          toAdd = relative;
+      }
+
+      if (isInternal) {
+        if (internalFiles)
+          internalFiles->push_back(toAdd);
+      } else {
+        if (isTemporary) {
+          if (tmpFiles)
+            tmpFiles->push_back(toAdd);
+        } else {
+          if (explicitFiles)
+            explicitFiles->push_back(toAdd);
+        }
+      }
+    }
+  }
+}
+
 } // namespace
 
 cmServerRequest::cmServerRequest(cmServer* server, const std::string& t,
@@ -317,6 +360,9 @@ const cmServerResponse cmServerProtocol1_0::Process(
 {
   assert(this->m_State >= STATE_ACTIVE);
 
+  if (request.Type == kCMAKE_INPUTS_TYPE) {
+    return this->ProcessCMakeInputs(request);
+  }
   if (request.Type == kCODE_MODEL_TYPE) {
     return this->ProcessCodeModel(request);
   }
@@ -341,6 +387,54 @@ bool cmServerProtocol1_0::IsExperimental() const
   return true;
 }
 
+cmServerResponse cmServerProtocol1_0::ProcessCMakeInputs(
+  const cmServerRequest& request)
+{
+  if (this->m_State < STATE_CONFIGURED) {
+    return request.ReportError("This instance was not yet configured.");
+  }
+
+  const cmake* cm = this->CMakeInstance();
+  const cmGlobalGenerator* gg = cm->GetGlobalGenerator();
+  const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot();
+  const std::string buildDir = cm->GetHomeOutputDirectory();
+  const std::string sourceDir = cm->GetHomeDirectory();
+
+  Json::Value result = Json::objectValue;
+  result[kSOURCE_DIRECTORY_KEY] = sourceDir;
+  result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir;
+
+  std::vector<std::string> internalFiles;
+  std::vector<std::string> explicitFiles;
+  std::vector<std::string> tmpFiles;
+  getCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles,
+                 &tmpFiles);
+
+  Json::Value array = Json::arrayValue;
+
+  Json::Value tmp = Json::objectValue;
+  tmp[kIS_CMAKE_KEY] = true;
+  tmp[kIS_TEMPORARY_KEY] = false;
+  tmp[kSOURCES_KEY] = fromStringList(internalFiles);
+  array.append(tmp);
+
+  tmp = Json::objectValue;
+  tmp[kIS_CMAKE_KEY] = false;
+  tmp[kIS_TEMPORARY_KEY] = false;
+  tmp[kSOURCES_KEY] = fromStringList(explicitFiles);
+  array.append(tmp);
+
+  tmp = Json::objectValue;
+  tmp[kIS_CMAKE_KEY] = false;
+  tmp[kIS_TEMPORARY_KEY] = true;
+  tmp[kSOURCES_KEY] = fromStringList(tmpFiles);
+  array.append(tmp);
+
+  result[kBUILD_FILES_KEY] = array;
+
+  return request.Reply(result);
+}
+
 class LanguageData
 {
 public:
@@ -732,6 +826,8 @@ cmServerResponse cmServerProtocol1_0::ProcessConfigure(
   std::string sourceDir = cm->GetHomeDirectory();
   const std::string buildDir = cm->GetHomeOutputDirectory();
 
+  cmGlobalGenerator* gg = cm->GetGlobalGenerator();
+
   if (buildDir.empty()) {
     return request.ReportError(
       "No build directory set via setGlobalSettings.");
@@ -752,8 +848,7 @@ cmServerResponse cmServerProtocol1_0::ProcessConfigure(
     const char* cachedGenerator =
       cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
     if (cachedGenerator) {
-      cmGlobalGenerator* gen = cm->GetGlobalGenerator();
-      if (gen && gen->GetName() != cachedGenerator) {
+      if (gg && gg->GetName() != cachedGenerator) {
         return request.ReportError("Configured generator does not match with "
                                    "CMAKE_GENERATOR found in cache.");
       }

+ 1 - 0
Source/cmServerProtocol.h

@@ -108,6 +108,7 @@ private:
                   std::string* errorMessage) override;
 
   // Handle requests:
+  cmServerResponse ProcessCMakeInputs(const cmServerRequest& request);
   cmServerResponse ProcessCodeModel(const cmServerRequest& request);
   cmServerResponse ProcessCompute(const cmServerRequest& request);
   cmServerResponse ProcessConfigure(const cmServerRequest& request);