server-mode: Add command to retrieve build system files

Add a command to retrieve files that are input to cmake itself.
This commit is contained in:
Tobias Hunger 2016-09-09 10:01:46 +02:00
parent ead71873b2
commit 84553a6e70
4 changed files with 144 additions and 2 deletions

View File

@ -558,3 +558,44 @@ listed by default.
Finally you can limit the target types that are going to be listed. This is
done by providing a list of target types as an array of strings to the
"targetTypes" key.
Type "cmakeInputs"
^^^^^^^^^^^^^^^^^^
The "cmakeInputs" requests will report files used by CMake as part
of the build system itself.
This request is only available after a project was successfully
"configure"d.
Example::
[== CMake Server ==[
{"type":"cmakeInputs"}
]== CMake Server ==]
CMake will reply with the following information::
[== CMake Server ==[
{"buildFiles":
[
{"isCMake":true,"isTemporary":false,"sources":["/usr/lib/cmake/...", ... ]},
{"isCMake":false,"isTemporary":false,"sources":["CMakeLists.txt", ...]},
{"isCMake":false,"isTemporary":true,"sources":["/tmp/build/CMakeFiles/...", ...]}
],
"cmakeRootDirectory":"/usr/lib/cmake",
"sourceDirectory":"/home/code/src/cmake",
"cookie":"",
"inReplyTo":"cmakeInputs",
"type":"reply"
}
]== CMake Server ==]
All file names are either relative to the top level source directory or
absolute.
The list of files which "isCMake" set to true are part of the cmake installation.
The list of files witch "isTemporary" set to true are part of the build directory
and will not survive the build directory getting cleaned out.

View File

@ -6,6 +6,7 @@
// Vocabulary:
static const std::string kCMAKE_INPUTS_TYPE = "cmakeInputs";
static const std::string kCODE_MODEL_TYPE = "codemodel";
static const std::string kCOMPUTE_TYPE = "compute";
static const std::string kCONFIGURE_TYPE = "configure";
@ -20,9 +21,11 @@ static const std::string kSIGNAL_TYPE = "signal";
static const std::string kARTIFACTS_KEY = "artifacts";
static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
static const std::string kBUILD_FILES_KEY = "buildFiles";
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 kCMAKE_ROOT_DIRECTORY_KEY = "cmakeRootDirectory";
static const std::string kCOMPILE_FLAGS_KEY = "compileFlags";
static const std::string kCONFIGURATIONS_KEY = "configurations";
static const std::string kCOOKIE_KEY = "cookie";
@ -35,9 +38,11 @@ static const std::string kFRAMEWORK_PATH_KEY = "frameworkPath";
static const std::string kFULL_NAME_KEY = "fullName";
static const std::string kGENERATOR_KEY = "generator";
static const std::string kINCLUDE_PATH_KEY = "includePath";
static const std::string kIS_CMAKE_KEY = "isCMake";
static const std::string kIS_EXPERIMENTAL_KEY = "isExperimental";
static const std::string kIS_GENERATED_KEY = "isGenerated";
static const std::string kIS_SYSTEM_KEY = "isSystem";
static const std::string kIS_TEMPORARY_KEY = "isTemporary";
static const std::string kLANGUAGE_KEY = "language";
static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage";
static const std::string kLINK_FLAGS_KEY = "linkFlags";

View File

@ -5,6 +5,7 @@
#include "cmExternalMakefileProjectGenerator.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmServer.h"
@ -61,6 +62,48 @@ static Json::Value fromStringList(const T& in)
return result;
}
static void getCMakeInputs(const cmGlobalGenerator* gg,
const std::string& sourceDir,
const std::string& buildDir,
std::vector<std::string>* internalFiles,
std::vector<std::string>* explicitFiles,
std::vector<std::string>* tmpFiles)
{
const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
const std::vector<cmMakefile*> makefiles = gg->GetMakefiles();
for (auto it = makefiles.begin(); it != makefiles.end(); ++it) {
const std::vector<std::string> listFiles = (*it)->GetListFiles();
for (auto jt = listFiles.begin(); jt != listFiles.end(); ++jt) {
const std::string startOfFile = jt->substr(0, cmakeRootDir.size());
const bool isInternal = (startOfFile == cmakeRootDir);
const bool isTemporary = !isInternal && (jt->find(buildDir + '/') == 0);
std::string toAdd = *jt;
if (!sourceDir.empty()) {
const std::string& relative =
cmSystemTools::RelativePath(sourceDir.c_str(), jt->c_str());
if (toAdd.size() > relative.size())
toAdd = relative;
}
if (isInternal) {
if (internalFiles)
internalFiles->push_back(toAdd);
} else {
if (isTemporary) {
if (tmpFiles)
tmpFiles->push_back(toAdd);
} else {
if (explicitFiles)
explicitFiles->push_back(toAdd);
}
}
}
}
}
} // namespace
cmServerRequest::cmServerRequest(cmServer* server, const std::string& t,
@ -317,6 +360,9 @@ const cmServerResponse cmServerProtocol1_0::Process(
{
assert(this->m_State >= STATE_ACTIVE);
if (request.Type == kCMAKE_INPUTS_TYPE) {
return this->ProcessCMakeInputs(request);
}
if (request.Type == kCODE_MODEL_TYPE) {
return this->ProcessCodeModel(request);
}
@ -341,6 +387,54 @@ bool cmServerProtocol1_0::IsExperimental() const
return true;
}
cmServerResponse cmServerProtocol1_0::ProcessCMakeInputs(
const cmServerRequest& request)
{
if (this->m_State < STATE_CONFIGURED) {
return request.ReportError("This instance was not yet configured.");
}
const cmake* cm = this->CMakeInstance();
const cmGlobalGenerator* gg = cm->GetGlobalGenerator();
const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot();
const std::string buildDir = cm->GetHomeOutputDirectory();
const std::string sourceDir = cm->GetHomeDirectory();
Json::Value result = Json::objectValue;
result[kSOURCE_DIRECTORY_KEY] = sourceDir;
result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir;
std::vector<std::string> internalFiles;
std::vector<std::string> explicitFiles;
std::vector<std::string> tmpFiles;
getCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles,
&tmpFiles);
Json::Value array = Json::arrayValue;
Json::Value tmp = Json::objectValue;
tmp[kIS_CMAKE_KEY] = true;
tmp[kIS_TEMPORARY_KEY] = false;
tmp[kSOURCES_KEY] = fromStringList(internalFiles);
array.append(tmp);
tmp = Json::objectValue;
tmp[kIS_CMAKE_KEY] = false;
tmp[kIS_TEMPORARY_KEY] = false;
tmp[kSOURCES_KEY] = fromStringList(explicitFiles);
array.append(tmp);
tmp = Json::objectValue;
tmp[kIS_CMAKE_KEY] = false;
tmp[kIS_TEMPORARY_KEY] = true;
tmp[kSOURCES_KEY] = fromStringList(tmpFiles);
array.append(tmp);
result[kBUILD_FILES_KEY] = array;
return request.Reply(result);
}
class LanguageData
{
public:
@ -732,6 +826,8 @@ cmServerResponse cmServerProtocol1_0::ProcessConfigure(
std::string sourceDir = cm->GetHomeDirectory();
const std::string buildDir = cm->GetHomeOutputDirectory();
cmGlobalGenerator* gg = cm->GetGlobalGenerator();
if (buildDir.empty()) {
return request.ReportError(
"No build directory set via setGlobalSettings.");
@ -752,8 +848,7 @@ cmServerResponse cmServerProtocol1_0::ProcessConfigure(
const char* cachedGenerator =
cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
if (cachedGenerator) {
cmGlobalGenerator* gen = cm->GetGlobalGenerator();
if (gen && gen->GetName() != cachedGenerator) {
if (gg && gg->GetName() != cachedGenerator) {
return request.ReportError("Configured generator does not match with "
"CMAKE_GENERATOR found in cache.");
}

View File

@ -108,6 +108,7 @@ private:
std::string* errorMessage) override;
// Handle requests:
cmServerResponse ProcessCMakeInputs(const cmServerRequest& request);
cmServerResponse ProcessCodeModel(const cmServerRequest& request);
cmServerResponse ProcessCompute(const cmServerRequest& request);
cmServerResponse ProcessConfigure(const cmServerRequest& request);