summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmServer.cxx3
-rw-r--r--Source/cmServerProtocol.cxx135
-rw-r--r--Source/cmServerProtocol.h18
3 files changed, 156 insertions, 0 deletions
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 7643b47..123b6a4 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -87,6 +87,8 @@ void read_stdin(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
cmServer::cmServer()
{
+ // Register supported protocols:
+ this->RegisterProtocol(new cmServerProtocol1_0);
}
cmServer::~cmServer()
@@ -245,6 +247,7 @@ cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request)
void cmServer::Serve()
{
+ assert(!this->SupportedProtocols.empty());
assert(!this->Protocol);
this->Loop = uv_default_loop();
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 659aa0f..c3a4d8e 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -14,6 +14,7 @@
#include "cmExternalMakefileProjectGenerator.h"
#include "cmServer.h"
+#include "cmSystemTools.h"
#include "cmake.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -24,7 +25,11 @@
namespace {
// Vocabulary:
+const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
const std::string kCOOKIE_KEY = "cookie";
+const std::string kEXTRA_GENERATOR_KEY = "extraGenerator";
+const std::string kGENERATOR_KEY = "generator";
+const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory";
const std::string kTYPE_KEY = "type";
} // namespace
@@ -127,3 +132,133 @@ bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
{
return true;
}
+
+std::pair<int, int> cmServerProtocol1_0::ProtocolVersion() const
+{
+ return std::make_pair(1, 0);
+}
+
+bool cmServerProtocol1_0::DoActivate(const cmServerRequest& request,
+ std::string* errorMessage)
+{
+ std::string sourceDirectory = request.Data[kSOURCE_DIRECTORY_KEY].asString();
+ const std::string buildDirectory =
+ request.Data[kBUILD_DIRECTORY_KEY].asString();
+ std::string generator = request.Data[kGENERATOR_KEY].asString();
+ std::string extraGenerator = request.Data[kEXTRA_GENERATOR_KEY].asString();
+
+ if (buildDirectory.empty()) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kBUILD_DIRECTORY_KEY + "\" is missing.";
+ return false;
+ }
+ cmake* cm = CMakeInstance();
+ if (cmSystemTools::PathExists(buildDirectory)) {
+ if (!cmSystemTools::FileIsDirectory(buildDirectory)) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kBUILD_DIRECTORY_KEY +
+ "\" exists but is not a directory.";
+ return false;
+ }
+
+ const std::string cachePath = cm->FindCacheFile(buildDirectory);
+ if (cm->LoadCache(cachePath)) {
+ cmState* state = cm->GetState();
+
+ // Check generator:
+ const std::string cachedGenerator =
+ std::string(state->GetCacheEntryValue("CMAKE_GENERATOR"));
+ if (cachedGenerator.empty() && generator.empty()) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kGENERATOR_KEY + "\" is required but unset.";
+ return false;
+ }
+ if (generator.empty()) {
+ generator = cachedGenerator;
+ }
+ if (generator != cachedGenerator) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kGENERATOR_KEY +
+ "\" set but incompatible with configured generator.";
+ return false;
+ }
+
+ // check extra generator:
+ const std::string cachedExtraGenerator =
+ std::string(state->GetCacheEntryValue("CMAKE_EXTRA_GENERATOR"));
+ if (!cachedExtraGenerator.empty() && !extraGenerator.empty() &&
+ cachedExtraGenerator != extraGenerator) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kEXTRA_GENERATOR_KEY +
+ "\" is set but incompatible with configured extra generator.";
+ return false;
+ }
+ if (extraGenerator.empty()) {
+ extraGenerator = cachedExtraGenerator;
+ }
+
+ // check sourcedir:
+ const std::string cachedSourceDirectory =
+ std::string(state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"));
+ if (!cachedSourceDirectory.empty() && !sourceDirectory.empty() &&
+ cachedSourceDirectory != sourceDirectory) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kSOURCE_DIRECTORY_KEY +
+ "\" is set but incompatible with configured source directory.";
+ return false;
+ }
+ if (sourceDirectory.empty()) {
+ sourceDirectory = cachedSourceDirectory;
+ }
+ }
+ }
+
+ if (sourceDirectory.empty()) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kSOURCE_DIRECTORY_KEY +
+ "\" is unset but required.";
+ return false;
+ }
+ if (!cmSystemTools::FileIsDirectory(sourceDirectory)) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kSOURCE_DIRECTORY_KEY + "\" is not a directory.";
+ return false;
+ }
+ if (generator.empty()) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kGENERATOR_KEY + "\" is unset but required.";
+ return false;
+ }
+
+ const std::string fullGeneratorName =
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+ generator, extraGenerator);
+
+ cmGlobalGenerator* gg = cm->CreateGlobalGenerator(fullGeneratorName);
+ if (!gg) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("Could not set up the requested combination of \"") +
+ kGENERATOR_KEY + "\" and \"" + kEXTRA_GENERATOR_KEY + "\"";
+ return false;
+ }
+
+ cm->SetGlobalGenerator(gg);
+ cm->SetHomeDirectory(sourceDirectory);
+ cm->SetHomeOutputDirectory(buildDirectory);
+
+ this->m_State = STATE_ACTIVE;
+ return true;
+}
+
+const cmServerResponse cmServerProtocol1_0::Process(
+ const cmServerRequest& request)
+{
+ assert(this->m_State >= STATE_ACTIVE);
+
+ return request.ReportError("Unknown command!");
+}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index e086f72..33183e9 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -95,3 +95,21 @@ protected:
private:
std::unique_ptr<cmake> m_CMakeInstance;
};
+
+class cmServerProtocol1_0 : public cmServerProtocol
+{
+public:
+ std::pair<int, int> ProtocolVersion() const override;
+ const cmServerResponse Process(const cmServerRequest& request) override;
+
+private:
+ bool DoActivate(const cmServerRequest& request,
+ std::string* errorMessage) override;
+
+ enum State
+ {
+ STATE_INACTIVE,
+ STATE_ACTIVE
+ };
+ State m_State = STATE_INACTIVE;
+};