cmake-server: Implement ServerProtocol 1.0
Enable the initial handshake of the client to complete the connection to the server. The handshake sets the protocol version that client and server will use to talk to each other. The only way to change this is to quit the server and start over. CMake specific information is also set during the initial handshake. Since cmake so far never had to change basic information about any project while running, it was decided to keep this information static and require a restart of the cmake server to change any of these.
This commit is contained in:
parent
b13d3e0d0b
commit
d341d077c5
|
@ -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();
|
||||
|
|
|
@ -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!");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue