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.
This commit is contained in:
Tobias Hunger 2016-09-09 10:01:45 +02:00 committed by Brad King
parent 544f65f44d
commit 0a8ad6700e
4 changed files with 121 additions and 1 deletions

View File

@ -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 ==]

View File

@ -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";

View File

@ -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)
{

View File

@ -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;
};