diff options
author | Brad King <brad.king@kitware.com> | 2016-09-27 12:22:50 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2016-09-27 12:22:50 (GMT) |
commit | e8ff565d94baf45df145dfef46e8cd40aedc08ff (patch) | |
tree | e5e59e4a8c0396f6980c951391cbb0eee2e72111 /Source | |
parent | e56eca3f6838d715fa10623a5ca538b3c9476493 (diff) | |
parent | 890432672bc9fe91365e5e5305285ab193e9060a (diff) | |
download | CMake-e8ff565d94baf45df145dfef46e8cd40aedc08ff.zip CMake-e8ff565d94baf45df145dfef46e8cd40aedc08ff.tar.gz CMake-e8ff565d94baf45df145dfef46e8cd40aedc08ff.tar.bz2 |
Merge topic 'cmake-server-basic-commands'
89043267 server-mode: Add command to compute the build system
0a8ad670 server-mode: Add a configure command
544f65f4 server-mode: Set global configuration of cmake via a command
82104cc7 server-mode: Query global configuration of cmake via a command
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmServerDictionary.h | 13 | ||||
-rw-r--r-- | Source/cmServerProtocol.cxx | 190 | ||||
-rw-r--r-- | Source/cmServerProtocol.h | 11 |
3 files changed, 213 insertions, 1 deletions
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h index 156ade2..fc1b44d 100644 --- a/Source/cmServerDictionary.h +++ b/Source/cmServerDictionary.h @@ -16,15 +16,23 @@ // Vocabulary: +static const std::string kCOMPUTE_TYPE = "compute"; +static const std::string kCONFIGURE_TYPE = "configure"; static const std::string kERROR_TYPE = "error"; +static const std::string kGLOBAL_SETTINGS_TYPE = "globalSettings"; static const std::string kHANDSHAKE_TYPE = "handshake"; static const std::string kMESSAGE_TYPE = "message"; static const std::string kPROGRESS_TYPE = "progress"; static const std::string kREPLY_TYPE = "reply"; +static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings"; static const std::string kSIGNAL_TYPE = "signal"; static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory"; +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 kCOOKIE_KEY = "cookie"; +static const std::string kDEBUG_OUTPUT_KEY = "debugOutput"; static const std::string kERROR_MESSAGE_KEY = "errorMessage"; static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator"; static const std::string kGENERATOR_KEY = "generator"; @@ -43,7 +51,12 @@ static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory"; static const std::string kSUPPORTED_PROTOCOL_VERSIONS = "supportedProtocolVersions"; 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 kWARN_UNINITIALIZED_KEY = "warnUninitialized"; +static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli"; +static const std::string kWARN_UNUSED_KEY = "warnUnused"; static const std::string kSTART_MAGIC = "[== CMake Server ==["; static const std::string kEND_MAGIC = "]== CMake Server ==]"; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 755de0c..134edf3 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -13,6 +13,7 @@ #include "cmServerProtocol.h" #include "cmExternalMakefileProjectGenerator.h" +#include "cmGlobalGenerator.h" #include "cmServer.h" #include "cmServerDictionary.h" #include "cmSystemTools.h" @@ -279,6 +280,19 @@ const cmServerResponse cmServerProtocol1_0::Process( { assert(this->m_State >= STATE_ACTIVE); + if (request.Type == kCOMPUTE_TYPE) { + return this->ProcessCompute(request); + } + if (request.Type == kCONFIGURE_TYPE) { + return this->ProcessConfigure(request); + } + if (request.Type == kGLOBAL_SETTINGS_TYPE) { + return this->ProcessGlobalSettings(request); + } + if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) { + return this->ProcessSetGlobalSettings(request); + } + return request.ReportError("Unknown command!"); } @@ -286,3 +300,179 @@ bool cmServerProtocol1_0::IsExperimental() const { return true; } + +cmServerResponse cmServerProtocol1_0::ProcessCompute( + const cmServerRequest& request) +{ + if (this->m_State > STATE_CONFIGURED) { + return request.ReportError("This build system was already generated."); + } + if (this->m_State < STATE_CONFIGURED) { + return request.ReportError("This project was not configured yet."); + } + + cmake* cm = this->CMakeInstance(); + int ret = cm->Generate(); + + if (ret < 0) { + return request.ReportError("Failed to compute build system."); + } + m_State = STATE_COMPUTED; + return request.Reply(Json::Value()); +} + +cmServerResponse cmServerProtocol1_0::ProcessConfigure( + const cmServerRequest& request) +{ + if (this->m_State == STATE_INACTIVE) { + return request.ReportError("This instance is inactive."); + } + + // Make sure the types of cacheArguments matches (if given): + std::vector<std::string> cacheArgs; + bool cacheArgumentsError = false; + const Json::Value passedArgs = request.Data[kCACHE_ARGUMENTS_KEY]; + if (!passedArgs.isNull()) { + if (passedArgs.isString()) { + cacheArgs.push_back(passedArgs.asString()); + } else if (passedArgs.isArray()) { + for (auto i = passedArgs.begin(); i != passedArgs.end(); ++i) { + if (!i->isString()) { + cacheArgumentsError = true; + break; + } + cacheArgs.push_back(i->asString()); + } + } else { + cacheArgumentsError = true; + } + } + if (cacheArgumentsError) { + request.ReportError( + "cacheArguments must be unset, a string or an array of strings."); + } + + cmake* cm = this->CMakeInstance(); + std::string sourceDir = cm->GetHomeDirectory(); + const std::string buildDir = cm->GetHomeOutputDirectory(); + + if (buildDir.empty()) { + return request.ReportError( + "No build directory set via setGlobalSettings."); + } + + if (cm->LoadCache(buildDir)) { + // build directory has been set up before + const char* cachedSourceDir = + cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"); + if (!cachedSourceDir) { + return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache."); + } + if (sourceDir.empty()) { + sourceDir = std::string(cachedSourceDir); + cm->SetHomeDirectory(sourceDir); + } + + const char* cachedGenerator = + cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR"); + if (cachedGenerator) { + cmGlobalGenerator* gen = cm->GetGlobalGenerator(); + if (gen && gen->GetName() != cachedGenerator) { + return request.ReportError("Configured generator does not match with " + "CMAKE_GENERATOR found in cache."); + } + } + } else { + // build directory has not been set up before + if (sourceDir.empty()) { + return request.ReportError("No sourceDirectory set via " + "setGlobalSettings and no cache found in " + "buildDirectory."); + } + } + + if (cm->AddCMakePaths() != 1) { + return request.ReportError("Failed to set CMake paths."); + } + + if (!cm->SetCacheArgs(cacheArgs)) { + return request.ReportError("cacheArguments could not be set."); + } + + int ret = cm->Configure(); + if (ret < 0) { + return request.ReportError("Configuration failed."); + } + m_State = STATE_CONFIGURED; + return request.Reply(Json::Value()); +} + +cmServerResponse cmServerProtocol1_0::ProcessGlobalSettings( + const cmServerRequest& request) +{ + cmake* cm = this->CMakeInstance(); + Json::Value obj = Json::objectValue; + + // Capabilities information: + obj[kCAPABILITIES_KEY] = cm->ReportCapabilitiesJson(true); + + obj[kDEBUG_OUTPUT_KEY] = cm->GetDebugOutput(); + obj[kTRACE_KEY] = cm->GetTrace(); + obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand(); + obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized(); + obj[kWARN_UNUSED_KEY] = cm->GetWarnUnused(); + obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli(); + obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars(); + + obj[kSOURCE_DIRECTORY_KEY] = cm->GetHomeDirectory(); + obj[kBUILD_DIRECTORY_KEY] = cm->GetHomeOutputDirectory(); + + // Currently used generator: + cmGlobalGenerator* gen = cm->GetGlobalGenerator(); + obj[kGENERATOR_KEY] = gen ? gen->GetName() : std::string(); + obj[kEXTRA_GENERATOR_KEY] = + gen ? gen->GetExtraGeneratorName() : std::string(); + + return request.Reply(obj); +} + +static void setBool(const cmServerRequest& request, const std::string& key, + std::function<void(bool)> setter) +{ + if (request.Data[key].isNull()) { + return; + } + setter(request.Data[key].asBool()); +} + +cmServerResponse cmServerProtocol1_0::ProcessSetGlobalSettings( + const cmServerRequest& request) +{ + const std::vector<std::string> boolValues = { + kDEBUG_OUTPUT_KEY, kTRACE_KEY, kTRACE_EXPAND_KEY, + kWARN_UNINITIALIZED_KEY, kWARN_UNUSED_KEY, kWARN_UNUSED_CLI_KEY, + kCHECK_SYSTEM_VARS_KEY + }; + for (auto i : boolValues) { + if (!request.Data[i].isNull() && !request.Data[i].isBool()) { + return request.ReportError("\"" + i + + "\" must be unset or a bool value."); + } + } + + cmake* cm = this->CMakeInstance(); + + setBool(request, kDEBUG_OUTPUT_KEY, + [cm](bool e) { cm->SetDebugOutputOn(e); }); + setBool(request, kTRACE_KEY, [cm](bool e) { cm->SetTrace(e); }); + setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); }); + setBool(request, kWARN_UNINITIALIZED_KEY, + [cm](bool e) { cm->SetWarnUninitialized(e); }); + setBool(request, kWARN_UNUSED_KEY, [cm](bool e) { cm->SetWarnUnused(e); }); + setBool(request, kWARN_UNUSED_CLI_KEY, + [cm](bool e) { cm->SetWarnUnusedCli(e); }); + setBool(request, kCHECK_SYSTEM_VARS_KEY, + [cm](bool e) { cm->SetCheckSystemVars(e); }); + + return request.Reply(Json::Value()); +} diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h index 0383dfe..e772eca 100644 --- a/Source/cmServerProtocol.h +++ b/Source/cmServerProtocol.h @@ -13,6 +13,7 @@ #pragma once #include "cmListFileCache.h" +#include "cmake.h" #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cm_jsoncpp_writer.h" @@ -116,10 +117,18 @@ private: bool DoActivate(const cmServerRequest& request, std::string* errorMessage) override; + // Handle requests: + cmServerResponse ProcessCompute(const cmServerRequest& request); + cmServerResponse ProcessConfigure(const cmServerRequest& request); + cmServerResponse ProcessGlobalSettings(const cmServerRequest& request); + cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request); + enum State { STATE_INACTIVE, - STATE_ACTIVE + STATE_ACTIVE, + STATE_CONFIGURED, + STATE_COMPUTED }; State m_State = STATE_INACTIVE; }; |