summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-server.7.rst27
-rw-r--r--Source/cmServerDictionary.h2
-rw-r--r--Source/cmServerProtocol.cxx89
-rw-r--r--Source/cmServerProtocol.h4
4 files changed, 121 insertions, 1 deletions
diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst
index cdd87d1..c5d4968 100644
--- a/Help/manual/cmake-server.7.rst
+++ b/Help/manual/cmake-server.7.rst
@@ -328,3 +328,30 @@ CMake will reply to this with::
[== CMake Server ==[
{"inReplyTo":"setGlobalSettings","type":"reply"}
]== CMake Server ==]
+
+
+Type "configure"
+^^^^^^^^^^^^^^^^
+
+This request will configure a project for build.
+
+To configure a build directory already containing cmake files, it is enough to
+set "buildDirectory" via "setGlobalSettings". To create a fresh build directory
+you also need to set "currentGenerator" and "sourceDirectory" via "setGlobalSettings"
+in addition to "buildDirectory".
+
+You may a list of strings to "configure" via the "cacheArguments" key. These
+strings will be interpreted similar to command line arguments related to
+cache handling that are passed to the cmake command line client.
+
+Example::
+
+ [== CMake Server ==[
+ {"type":"configure", "cacheArguments":["-Dsomething=else"]}
+ ]== CMake Server ==]
+
+CMake will reply like this (after reporting progress for some time)::
+
+ [== CMake Server ==[
+ {"cookie":"","inReplyTo":"configure","type":"reply"}
+ ]== CMake Server ==]
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
index 657fbd6..b78a1f4 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 55ae24e..06f5177 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<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)
{
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 21515b2..c0148a4 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;
};