From 0a8ad6700eb7f54961271b3ee7b41add61eb0be5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 9 Sep 2016 10:01:45 +0200 Subject: server-mode: Add a configure command Add a command to trigger cmake to configure a project. Keep this separate from the compute step (added in the next commit) to faciliate applications like cmake-gui. --- Source/cmServerDictionary.h | 2 + Source/cmServerProtocol.cxx | 89 +++++++++++++++++++++++++++++++++++++++++++++ Source/cmServerProtocol.h | 4 +- 3 files changed, 94 insertions(+), 1 deletion(-) (limited to 'Source') diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h index 657fbd6389..b78a1f40b9 100644 --- a/Source/cmServerDictionary.h +++ b/Source/cmServerDictionary.h @@ -16,6 +16,7 @@ // Vocabulary: +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"; @@ -26,6 +27,7 @@ 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"; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 55ae24e9dc..06f5177185 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -280,6 +280,9 @@ const cmServerResponse cmServerProtocol1_0::Process( { assert(this->m_State >= STATE_ACTIVE); + if (request.Type == kCONFIGURE_TYPE) { + return this->ProcessConfigure(request); + } if (request.Type == kGLOBAL_SETTINGS_TYPE) { return this->ProcessGlobalSettings(request); } @@ -295,6 +298,92 @@ bool cmServerProtocol1_0::IsExperimental() const return true; } +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 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) { diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h index 21515b28eb..c0148a4504 100644 --- a/Source/cmServerProtocol.h +++ b/Source/cmServerProtocol.h @@ -118,13 +118,15 @@ private: std::string* errorMessage) override; // Handle requests: + 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 m_State = STATE_INACTIVE; }; -- cgit v1.2.1