From 7b1e60f26e284e223be8638744ba3a3b0efdee63 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 9 Sep 2016 10:01:46 +0200 Subject: [PATCH] server-mode: Report CMakeCache entries With this it would be possible to implement something like cmake-gui using server-mode. --- Help/manual/cmake-server.7.rst | 36 +++++++++++++++++++ Source/cmServerDictionary.h | 6 ++++ Source/cmServerProtocol.cxx | 64 ++++++++++++++++++++++++++++++++++ Source/cmServerProtocol.h | 1 + 4 files changed, 107 insertions(+) diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst index 76ee3fb91..f66212522 100644 --- a/Help/manual/cmake-server.7.rst +++ b/Help/manual/cmake-server.7.rst @@ -599,3 +599,39 @@ 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. + + +Type "cache" +^^^^^^^^^^^^ + +The "cache" request can be used once a project is configured and will +list the cached configuration values. + +Example:: + + [== CMake Server ==[ + {"type":"cache"} + ]== CMake Server ==] + +CMake will respond with the following output:: + + [== CMake Server ==[ + { + "cookie":"","inReplyTo":"cache","type":"reply", + "cache": + [ + { + "key":"SOMEVALUE", + "properties": + { + "ADVANCED":"1", + "HELPSTRING":"This is not helpful" + } + "type":"STRING", + "value":"TEST"} + ] + } + ]== CMake Server ==] + +The output can be limited to a list of keys by passing an array of key names +to the "keys" optional field of the "cache" request. diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h index bccce550b..c811b83af 100644 --- a/Source/cmServerDictionary.h +++ b/Source/cmServerDictionary.h @@ -6,6 +6,7 @@ // Vocabulary: +static const std::string kCACHE_TYPE = "cache"; static const std::string kCMAKE_INPUTS_TYPE = "cmakeInputs"; static const std::string kCODE_MODEL_TYPE = "codemodel"; static const std::string kCOMPUTE_TYPE = "compute"; @@ -23,6 +24,7 @@ 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 kCACHE_KEY = "cache"; 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"; @@ -43,6 +45,8 @@ 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 kKEY_KEY = "key"; +static const std::string kKEYS_KEY = "keys"; static const std::string kLANGUAGE_KEY = "language"; static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage"; static const std::string kLINK_FLAGS_KEY = "linkFlags"; @@ -59,6 +63,7 @@ static const std::string kPROGRESS_MAXIMUM_KEY = "progressMaximum"; static const std::string kPROGRESS_MESSAGE_KEY = "progressMessage"; static const std::string kPROGRESS_MINIMUM_KEY = "progressMinimum"; static const std::string kPROJECTS_KEY = "projects"; +static const std::string kPROPERTIES_KEY = "properties"; static const std::string kPROTOCOL_VERSION_KEY = "protocolVersion"; static const std::string kREPLY_TO_KEY = "inReplyTo"; static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory"; @@ -71,6 +76,7 @@ static const std::string kTITLE_KEY = "title"; static const std::string kTRACE_EXPAND_KEY = "traceExpand"; static const std::string kTRACE_KEY = "trace"; static const std::string kTYPE_KEY = "type"; +static const std::string kVALUE_KEY = "value"; static const std::string kWARN_UNINITIALIZED_KEY = "warnUninitialized"; static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli"; static const std::string kWARN_UNUSED_KEY = "warnUnused"; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 00a813579..f083e49fe 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmServerProtocol.h" +#include "cmCacheManager.h" #include "cmExternalMakefileProjectGenerator.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -62,6 +63,15 @@ static Json::Value fromStringList(const T& in) return result; } +static std::vector toStringList(const Json::Value& in) +{ + std::vector result; + for (const auto& it : in) { + result.push_back(it.asString()); + } + return result; +} + static void getCMakeInputs(const cmGlobalGenerator* gg, const std::string& sourceDir, const std::string& buildDir, @@ -360,6 +370,9 @@ const cmServerResponse cmServerProtocol1_0::Process( { assert(this->m_State >= STATE_ACTIVE); + if (request.Type == kCACHE_TYPE) { + return this->ProcessCache(request); + } if (request.Type == kCMAKE_INPUTS_TYPE) { return this->ProcessCMakeInputs(request); } @@ -387,6 +400,57 @@ bool cmServerProtocol1_0::IsExperimental() const return true; } +cmServerResponse cmServerProtocol1_0::ProcessCache( + const cmServerRequest& request) +{ + if (this->m_State < STATE_CONFIGURED) { + return request.ReportError("This project was not configured yet."); + } + + cmState* state = this->CMakeInstance()->GetState(); + + Json::Value result = Json::objectValue; + + std::vector allKeys = state->GetCacheEntryKeys(); + + Json::Value list = Json::arrayValue; + std::vector keys = toStringList(request.Data[kKEYS_KEY]); + if (keys.empty()) { + keys = allKeys; + } else { + for (auto i : keys) { + if (std::find_if(allKeys.begin(), allKeys.end(), + [i](const std::string& j) { return i == j; }) == + allKeys.end()) { + return request.ReportError("Key \"" + i + "\" not found in cache."); + } + } + } + std::sort(keys.begin(), keys.end()); + for (auto key : keys) { + Json::Value entry = Json::objectValue; + entry[kKEY_KEY] = key; + entry[kTYPE_KEY] = + cmState::CacheEntryTypeToString(state->GetCacheEntryType(key)); + entry[kVALUE_KEY] = state->GetCacheEntryValue(key); + + Json::Value props = Json::objectValue; + bool haveProperties = false; + for (auto prop : state->GetCacheEntryPropertyList(key)) { + haveProperties = true; + props[prop] = state->GetCacheEntryProperty(key, prop); + } + if (haveProperties) { + entry[kPROPERTIES_KEY] = props; + } + + list.append(entry); + } + + result[kCACHE_KEY] = list; + return request.Reply(result); +} + cmServerResponse cmServerProtocol1_0::ProcessCMakeInputs( const cmServerRequest& request) { diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h index 2a6b1937c..d672a60b6 100644 --- a/Source/cmServerProtocol.h +++ b/Source/cmServerProtocol.h @@ -108,6 +108,7 @@ private: std::string* errorMessage) override; // Handle requests: + cmServerResponse ProcessCache(const cmServerRequest& request); cmServerResponse ProcessCMakeInputs(const cmServerRequest& request); cmServerResponse ProcessCodeModel(const cmServerRequest& request); cmServerResponse ProcessCompute(const cmServerRequest& request);