From fc43492e44c67ed73a6483a4cd587eae02657949 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 27 Aug 2018 10:02:50 -0400 Subject: cmake: Factor json version object construction into helper --- Source/cmake.cxx | 13 +++++++++---- Source/cmake.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 6c14834..c26a380 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -225,10 +225,8 @@ cmake::~cmake() } #if defined(CMAKE_BUILD_WITH_CMAKE) -Json::Value cmake::ReportCapabilitiesJson(bool haveServerMode) const +Json::Value cmake::ReportVersionJson() const { - Json::Value obj = Json::objectValue; - // Version information: Json::Value version = Json::objectValue; version["string"] = CMake_VERSION; version["major"] = CMake_VERSION_MAJOR; @@ -236,8 +234,15 @@ Json::Value cmake::ReportCapabilitiesJson(bool haveServerMode) const version["suffix"] = CMake_VERSION_SUFFIX; version["isDirty"] = (CMake_VERSION_IS_DIRTY == 1); version["patch"] = CMake_VERSION_PATCH; + return version; +} - obj["version"] = version; +Json::Value cmake::ReportCapabilitiesJson(bool haveServerMode) const +{ + Json::Value obj = Json::objectValue; + + // Version information: + obj["version"] = this->ReportVersionJson(); // Generators: std::vector generatorInfoList; diff --git a/Source/cmake.h b/Source/cmake.h index f7dc3f7..d3d0e80 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -128,6 +128,7 @@ public: ~cmake(); #if defined(CMAKE_BUILD_WITH_CMAKE) + Json::Value ReportVersionJson() const; Json::Value ReportCapabilitiesJson(bool haveServerMode) const; #endif std::string ReportCapabilities(bool haveServerMode) const; -- cgit v0.12 From aabce528519eaa1db64fb4eef48e12669b028f05 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 21 Sep 2018 09:35:28 -0400 Subject: server: factor out json object generation entry points Make entry points for these that do not reference the server code. For now we leave the "cache" object generation alone because its implementation interleaves error handling and the format may not suitable outside a server response. --- Source/cmServerProtocol.cxx | 54 ++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 2cad657..266d05c 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -550,23 +550,12 @@ cmServerResponse cmServerProtocol1::ProcessCache( return request.Reply(result); } -cmServerResponse cmServerProtocol1::ProcessCMakeInputs( - const cmServerRequest& request) +static Json::Value DumpCMakeInputs(const cmake* cm) { - 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 internalFiles; std::vector explicitFiles; std::vector tmpFiles; @@ -593,8 +582,24 @@ cmServerResponse cmServerProtocol1::ProcessCMakeInputs( tmp[kSOURCES_KEY] = fromStringList(tmpFiles); array.append(tmp); - result[kBUILD_FILES_KEY] = array; + return array; +} + +cmServerResponse cmServerProtocol1::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 std::string cmakeRootDir = cmSystemTools::GetCMakeRoot(); + const std::string& sourceDir = cm->GetHomeDirectory(); + + Json::Value result = Json::objectValue; + result[kSOURCE_DIRECTORY_KEY] = sourceDir; + result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir; + result[kBUILD_FILES_KEY] = DumpCMakeInputs(cm); return request.Reply(result); } @@ -958,6 +963,13 @@ static Json::Value DumpCTestConfigurationsList(const cmake* cm) return result; } +static Json::Value DumpCTestInfo(const cmake* cm) +{ + Json::Value result = Json::objectValue; + result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm); + return result; +} + static void GetTargetProperty( cmGeneratorExpressionInterpreter& genexInterpreter, cmGeneratorTarget* target, const char* propertyName, @@ -1256,6 +1268,13 @@ static Json::Value DumpConfigurationsList(const cmake* cm) return result; } +static Json::Value DumpCodeModel(const cmake* cm) +{ + Json::Value result = Json::objectValue; + result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm); + return result; +} + cmServerResponse cmServerProtocol1::ProcessCodeModel( const cmServerRequest& request) { @@ -1263,9 +1282,7 @@ cmServerResponse cmServerProtocol1::ProcessCodeModel( return request.ReportError("No build system was generated yet."); } - Json::Value result = Json::objectValue; - result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(this->CMakeInstance()); - return request.Reply(result); + return request.Reply(DumpCodeModel(this->CMakeInstance())); } cmServerResponse cmServerProtocol1::ProcessCompute( @@ -1488,10 +1505,7 @@ cmServerResponse cmServerProtocol1::ProcessCTests( return request.ReportError("This instance was not yet computed."); } - Json::Value result = Json::objectValue; - result[kCONFIGURATIONS_KEY] = - DumpCTestConfigurationsList(this->CMakeInstance()); - return request.Reply(result); + return request.Reply(DumpCTestInfo(this->CMakeInstance())); } cmServerProtocol1::GeneratorInformation::GeneratorInformation( -- cgit v0.12 From 85be67217bea4f1f655b16fdd6ac938800a96326 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 21 Sep 2018 09:59:04 -0400 Subject: server: Split json object generation into separate source For now just move the content and `#include` it back in to the original translation unit. That way `git blame` can cleanly track the original lines. --- Source/cmJsonObjects.cxx | 819 ++++++++++++++++++++++++++++++++++++++++++++ Source/cmServerProtocol.cxx | 803 +------------------------------------------ 2 files changed, 821 insertions(+), 801 deletions(-) create mode 100644 Source/cmJsonObjects.cxx diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx new file mode 100644 index 0000000..b534471 --- /dev/null +++ b/Source/cmJsonObjects.cxx @@ -0,0 +1,819 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmGeneratorExpression.h" +#include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" +#include "cmInstallGenerator.h" +#include "cmInstallTargetGenerator.h" +#include "cmLinkLineComputer.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmProperty.h" +#include "cmSourceFile.h" +#include "cmState.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" +#include "cmStateTypes.h" +#include "cmSystemTools.h" +#include "cmTarget.h" +#include "cmTest.h" +#include "cmake.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +std::vector getConfigurations(const cmake* cm) +{ + std::vector configurations; + auto makefiles = cm->GetGlobalGenerator()->GetMakefiles(); + if (makefiles.empty()) { + return configurations; + } + + makefiles[0]->GetConfigurations(configurations); + if (configurations.empty()) { + configurations.push_back(""); + } + return configurations; +} + +bool hasString(const Json::Value& v, const std::string& s) +{ + return !v.isNull() && + std::any_of(v.begin(), v.end(), + [s](const Json::Value& i) { return i.asString() == s; }); +} + +template +Json::Value fromStringList(const T& in) +{ + Json::Value result = Json::arrayValue; + for (std::string const& i : in) { + result.append(i); + } + return result; +} + +void getCMakeInputs(const cmGlobalGenerator* gg, const std::string& sourceDir, + const std::string& buildDir, + std::vector* internalFiles, + std::vector* explicitFiles, + std::vector* tmpFiles) +{ + const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/'; + std::vector const& makefiles = gg->GetMakefiles(); + for (cmMakefile const* mf : makefiles) { + for (std::string const& lf : mf->GetListFiles()) { + + const std::string startOfFile = lf.substr(0, cmakeRootDir.size()); + const bool isInternal = (startOfFile == cmakeRootDir); + const bool isTemporary = !isInternal && (lf.find(buildDir + '/') == 0); + + std::string toAdd = lf; + if (!sourceDir.empty()) { + const std::string& relative = + cmSystemTools::RelativePath(sourceDir, lf); + if (toAdd.size() > relative.size()) { + toAdd = relative; + } + } + + if (isInternal) { + if (internalFiles) { + internalFiles->push_back(std::move(toAdd)); + } + } else { + if (isTemporary) { + if (tmpFiles) { + tmpFiles->push_back(std::move(toAdd)); + } + } else { + if (explicitFiles) { + explicitFiles->push_back(std::move(toAdd)); + } + } + } + } + } +} + +} // namespace + +static Json::Value DumpCMakeInputs(const cmake* cm) +{ + const cmGlobalGenerator* gg = cm->GetGlobalGenerator(); + const std::string& buildDir = cm->GetHomeOutputDirectory(); + const std::string& sourceDir = cm->GetHomeDirectory(); + + std::vector internalFiles; + std::vector explicitFiles; + std::vector 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); + + return array; +} + +const std::string kInterfaceSourcesLanguageDataKey = + "INTERFACE_SOURCES_LD_KEY"; +class LanguageData +{ +public: + bool operator==(const LanguageData& other) const; + + void SetDefines(const std::set& defines); + + bool IsGenerated = false; + std::string Language; + std::string Flags; + std::vector Defines; + std::vector> IncludePathList; +}; + +bool LanguageData::operator==(const LanguageData& other) const +{ + return Language == other.Language && Defines == other.Defines && + Flags == other.Flags && IncludePathList == other.IncludePathList && + IsGenerated == other.IsGenerated; +} + +void LanguageData::SetDefines(const std::set& defines) +{ + std::vector result; + result.reserve(defines.size()); + for (std::string const& i : defines) { + result.push_back(i); + } + std::sort(result.begin(), result.end()); + Defines = std::move(result); +} + +struct FileGroupSources +{ + bool IsInterfaceSources; + std::vector Files; +}; + +namespace std { + +template <> +struct hash +{ + std::size_t operator()(const LanguageData& in) const + { + using std::hash; + size_t result = + hash()(in.Language) ^ hash()(in.Flags); + for (auto const& i : in.IncludePathList) { + result = result ^ + (hash()(i.first) ^ + (i.second ? std::numeric_limits::max() : 0)); + } + for (auto const& i : in.Defines) { + result = result ^ hash()(i); + } + result = + result ^ (in.IsGenerated ? std::numeric_limits::max() : 0); + return result; + } +}; + +} // namespace std + +static Json::Value DumpSourceFileGroup(const LanguageData& data, + bool isInterfaceSource, + const std::vector& files, + const std::string& baseDir) +{ + Json::Value result = Json::objectValue; + + if (isInterfaceSource) { + result[kIS_INTERFACE_SOURCES_KEY] = true; + } + if (!data.Language.empty()) { + result[kLANGUAGE_KEY] = data.Language; + } + if (!data.Flags.empty()) { + result[kCOMPILE_FLAGS_KEY] = data.Flags; + } + if (!data.IncludePathList.empty()) { + Json::Value includes = Json::arrayValue; + for (auto const& i : data.IncludePathList) { + Json::Value tmp = Json::objectValue; + tmp[kPATH_KEY] = i.first; + if (i.second) { + tmp[kIS_SYSTEM_KEY] = i.second; + } + includes.append(tmp); + } + result[kINCLUDE_PATH_KEY] = includes; + } + if (!data.Defines.empty()) { + result[kDEFINES_KEY] = fromStringList(data.Defines); + } + + result[kIS_GENERATED_KEY] = data.IsGenerated; + + Json::Value sourcesValue = Json::arrayValue; + for (auto const& i : files) { + const std::string relPath = cmSystemTools::RelativePath(baseDir, i); + sourcesValue.append(relPath.size() < i.size() ? relPath : i); + } + + result[kSOURCES_KEY] = sourcesValue; + return result; +} + +static void PopulateFileGroupData( + cmGeneratorTarget* target, bool isInterfaceSources, + const std::vector& files, const std::string& config, + const std::map& languageDataMap, + std::unordered_map& fileGroups) +{ + for (cmSourceFile* file : files) { + LanguageData fileData; + fileData.Language = file->GetLanguage(); + if (!fileData.Language.empty() || isInterfaceSources) { + const LanguageData& ld = isInterfaceSources + ? languageDataMap.at(kInterfaceSourcesLanguageDataKey) + : languageDataMap.at(fileData.Language); + cmLocalGenerator* lg = target->GetLocalGenerator(); + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, + fileData.Language); + + std::string compileFlags = ld.Flags; + const std::string COMPILE_FLAGS("COMPILE_FLAGS"); + if (const char* cflags = file->GetProperty(COMPILE_FLAGS)) { + lg->AppendFlags(compileFlags, + genexInterpreter.Evaluate(cflags, COMPILE_FLAGS)); + } + const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); + if (const char* coptions = file->GetProperty(COMPILE_OPTIONS)) { + lg->AppendCompileOptions( + compileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS)); + } + fileData.Flags = compileFlags; + + // Add include directories from source file properties. + std::vector includes; + + const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); + if (const char* cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) { + const std::string& evaluatedIncludes = + genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES); + lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file); + + for (const auto& include : includes) { + // INTERFACE_LIBRARY targets do not support the + // IsSystemIncludeDirectory call so just set it to false. + const bool isSystemInclude = isInterfaceSources + ? false + : target->IsSystemIncludeDirectory(include, config, + fileData.Language); + fileData.IncludePathList.push_back( + std::make_pair(include, isSystemInclude)); + } + } + + fileData.IncludePathList.insert(fileData.IncludePathList.end(), + ld.IncludePathList.begin(), + ld.IncludePathList.end()); + + const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); + std::set defines; + if (const char* defs = file->GetProperty(COMPILE_DEFINITIONS)) { + lg->AppendDefines( + defines, genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS)); + } + + const std::string defPropName = + "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config); + if (const char* config_defs = file->GetProperty(defPropName)) { + lg->AppendDefines( + defines, + genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS)); + } + + defines.insert(ld.Defines.begin(), ld.Defines.end()); + + fileData.SetDefines(defines); + } + + fileData.IsGenerated = file->GetPropertyAsBool("GENERATED"); + FileGroupSources& groupFileList = fileGroups[fileData]; + groupFileList.IsInterfaceSources = isInterfaceSources; + groupFileList.Files.push_back(file->GetFullPath()); + } +} + +static Json::Value DumpSourceFilesList( + cmGeneratorTarget* target, const std::string& config, + const std::map& languageDataMap) +{ + const cmStateEnums::TargetType type = target->GetType(); + std::unordered_map fileGroups; + + // Collect sourcefile groups: + + std::vector files; + if (type == cmStateEnums::INTERFACE_LIBRARY) { + // INTERFACE_LIBRARY targets do not create all the data structures + // associated with regular targets. If properties are explicitly specified + // for files in INTERFACE_SOURCES then we can get them through the Makefile + // rather than the target. + files = target->Makefile->GetSourceFiles(); + } else { + target->GetSourceFiles(files, config); + PopulateFileGroupData(target, false /* isInterfaceSources */, files, + config, languageDataMap, fileGroups); + } + + // Collect interface sourcefile groups: + + auto targetProp = target->Target->GetProperty("INTERFACE_SOURCES"); + if (targetProp != nullptr) { + cmGeneratorExpressionInterpreter genexInterpreter( + target->GetLocalGenerator(), config, target); + + auto evaluatedSources = cmsys::SystemTools::SplitString( + genexInterpreter.Evaluate(targetProp, "INTERFACE_SOURCES"), ';'); + + std::map filesMap; + for (auto file : files) { + filesMap[file->GetFullPath()] = file; + } + + std::vector interfaceSourceFiles; + for (const std::string& interfaceSourceFilePath : evaluatedSources) { + auto entry = filesMap.find(interfaceSourceFilePath); + if (entry != filesMap.end()) { + // use what we have since it has all the associated properties + interfaceSourceFiles.push_back(entry->second); + } else { + interfaceSourceFiles.push_back( + new cmSourceFile(target->Makefile, interfaceSourceFilePath)); + } + } + + PopulateFileGroupData(target, true /* isInterfaceSources */, + interfaceSourceFiles, config, languageDataMap, + fileGroups); + } + + const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory(); + Json::Value result = Json::arrayValue; + for (auto const& it : fileGroups) { + Json::Value group = DumpSourceFileGroup( + it.first, it.second.IsInterfaceSources, it.second.Files, baseDir); + if (!group.isNull()) { + result.append(group); + } + } + + return result; +} + +static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo, + const std::string& config) +{ + Json::Value result = Json::objectValue; + result[kCTEST_NAME] = testInfo->GetName(); + + // Concat command entries together. After the first should be the arguments + // for the command + std::string command; + for (auto const& cmd : testInfo->GetCommand()) { + command.append(cmd); + command.append(" "); + } + + // Remove any config specific variables from the output. + cmGeneratorExpression ge; + auto cge = ge.Parse(command); + const std::string& processed = cge->Evaluate(lg, config); + result[kCTEST_COMMAND] = processed; + + // Build up the list of properties that may have been specified + Json::Value properties = Json::arrayValue; + for (auto& prop : testInfo->GetProperties()) { + Json::Value entry = Json::objectValue; + entry[kKEY_KEY] = prop.first; + + // Remove config variables from the value too. + auto cge_value = ge.Parse(prop.second.GetValue()); + const std::string& processed_value = cge_value->Evaluate(lg, config); + entry[kVALUE_KEY] = processed_value; + properties.append(entry); + } + result[kPROPERTIES_KEY] = properties; + + return result; +} + +static void DumpMakefileTests(cmLocalGenerator* lg, const std::string& config, + Json::Value* result) +{ + auto mf = lg->GetMakefile(); + std::vector tests; + mf->GetTests(config, tests); + for (auto test : tests) { + Json::Value tmp = DumpCTestInfo(lg, test, config); + if (!tmp.isNull()) { + result->append(tmp); + } + } +} + +static Json::Value DumpCTestProjectList(const cmake* cm, + std::string const& config) +{ + Json::Value result = Json::arrayValue; + + auto globalGen = cm->GetGlobalGenerator(); + + for (const auto& projectIt : globalGen->GetProjectMap()) { + Json::Value pObj = Json::objectValue; + pObj[kNAME_KEY] = projectIt.first; + + Json::Value tests = Json::arrayValue; + + // Gather tests for every generator + for (const auto& lg : projectIt.second) { + // Make sure they're generated. + lg->GenerateTestFiles(); + DumpMakefileTests(lg, config, &tests); + } + + pObj[kCTEST_INFO] = tests; + + result.append(pObj); + } + + return result; +} + +static Json::Value DumpCTestConfiguration(const cmake* cm, + const std::string& config) +{ + Json::Value result = Json::objectValue; + result[kNAME_KEY] = config; + + result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config); + + return result; +} + +static Json::Value DumpCTestConfigurationsList(const cmake* cm) +{ + Json::Value result = Json::arrayValue; + + for (const std::string& c : getConfigurations(cm)) { + result.append(DumpCTestConfiguration(cm, c)); + } + + return result; +} + +static Json::Value DumpCTestInfo(const cmake* cm) +{ + Json::Value result = Json::objectValue; + result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm); + return result; +} + +static void GetTargetProperty( + cmGeneratorExpressionInterpreter& genexInterpreter, + cmGeneratorTarget* target, const char* propertyName, + std::vector& propertyValue) +{ + auto targetProp = target->Target->GetProperty(propertyName); + if (targetProp != nullptr) { + propertyValue = cmsys::SystemTools::SplitString( + genexInterpreter.Evaluate(targetProp, propertyName), ';'); + } +} + +static void CreateInterfaceSourcesEntry( + cmLocalGenerator* lg, cmGeneratorTarget* target, const std::string& config, + std::map& languageDataMap) +{ + LanguageData& ld = languageDataMap[kInterfaceSourcesLanguageDataKey]; + ld.Language = ""; + + cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target); + std::vector propertyValue; + GetTargetProperty(genexInterpreter, target, "INTERFACE_INCLUDE_DIRECTORIES", + propertyValue); + for (std::string const& i : propertyValue) { + ld.IncludePathList.push_back( + std::make_pair(i, false /* isSystemInclude */)); + } + + propertyValue.clear(); + GetTargetProperty(genexInterpreter, target, + "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", propertyValue); + for (std::string const& i : propertyValue) { + ld.IncludePathList.push_back( + std::make_pair(i, true /* isSystemInclude */)); + } + + propertyValue.clear(); + GetTargetProperty(genexInterpreter, target, "INTERFACE_COMPILE_OPTIONS", + propertyValue); + for (const auto& s : propertyValue) { + ld.Flags += " " + s; + } + + propertyValue.clear(); + GetTargetProperty(genexInterpreter, target, "INTERFACE_COMPILE_DEFINITIONS", + propertyValue); + if (!propertyValue.empty()) { + std::set defines(propertyValue.begin(), propertyValue.end()); + ld.SetDefines(defines); + } +} + +static Json::Value DumpTarget(cmGeneratorTarget* target, + const std::string& config) +{ + cmLocalGenerator* lg = target->GetLocalGenerator(); + const cmState* state = lg->GetState(); + + const cmStateEnums::TargetType type = target->GetType(); + const std::string typeName = state->GetTargetTypeName(type); + + Json::Value ttl = Json::arrayValue; + ttl.append("EXECUTABLE"); + ttl.append("STATIC_LIBRARY"); + ttl.append("SHARED_LIBRARY"); + ttl.append("MODULE_LIBRARY"); + ttl.append("OBJECT_LIBRARY"); + ttl.append("UTILITY"); + ttl.append("INTERFACE_LIBRARY"); + + if (!hasString(ttl, typeName) || target->IsImported()) { + return Json::Value(); + } + + Json::Value result = Json::objectValue; + result[kNAME_KEY] = target->GetName(); + result[kIS_GENERATOR_PROVIDED_KEY] = + target->Target->GetIsGeneratorProvided(); + result[kTYPE_KEY] = typeName; + result[kSOURCE_DIRECTORY_KEY] = lg->GetCurrentSourceDirectory(); + result[kBUILD_DIRECTORY_KEY] = lg->GetCurrentBinaryDirectory(); + result[kFULL_NAME_KEY] = target->GetFullName(config); + + if (target->Target->GetHaveInstallRule()) { + result[kHAS_INSTALL_RULE] = true; + + Json::Value installPaths = Json::arrayValue; + auto targetGenerators = target->Makefile->GetInstallGenerators(); + for (auto installGenerator : targetGenerators) { + auto installTargetGenerator = + dynamic_cast(installGenerator); + if (installTargetGenerator != nullptr && + installTargetGenerator->GetTarget()->Target == target->Target) { + auto dest = installTargetGenerator->GetDestination(config); + + std::string installPath; + if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) { + installPath = dest; + } else { + std::string installPrefix = + target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); + installPath = installPrefix + '/' + dest; + } + + installPaths.append(installPath); + } + } + + result[kINSTALL_PATHS] = installPaths; + } + + if (target->HaveWellDefinedOutputFiles()) { + Json::Value artifacts = Json::arrayValue; + artifacts.append( + target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact)); + if (target->IsDLLPlatform()) { + artifacts.append( + target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact)); + const cmGeneratorTarget::OutputInfo* output = + target->GetOutputInfo(config); + if (output && !output->PdbDir.empty()) { + artifacts.append(output->PdbDir + '/' + target->GetPDBName(config)); + } + } + result[kARTIFACTS_KEY] = artifacts; + + result[kLINKER_LANGUAGE_KEY] = target->GetLinkerLanguage(config); + + std::string linkLibs; + std::string linkFlags; + std::string linkLanguageFlags; + std::string frameworkPath; + std::string linkPath; + cmLinkLineComputer linkLineComputer(lg, + lg->GetStateSnapshot().GetDirectory()); + lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags, + linkFlags, frameworkPath, linkPath, target); + + linkLibs = cmSystemTools::TrimWhitespace(linkLibs); + linkFlags = cmSystemTools::TrimWhitespace(linkFlags); + linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags); + frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath); + linkPath = cmSystemTools::TrimWhitespace(linkPath); + + if (!cmSystemTools::TrimWhitespace(linkLibs).empty()) { + result[kLINK_LIBRARIES_KEY] = linkLibs; + } + if (!cmSystemTools::TrimWhitespace(linkFlags).empty()) { + result[kLINK_FLAGS_KEY] = linkFlags; + } + if (!cmSystemTools::TrimWhitespace(linkLanguageFlags).empty()) { + result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags; + } + if (!frameworkPath.empty()) { + result[kFRAMEWORK_PATH_KEY] = frameworkPath; + } + if (!linkPath.empty()) { + result[kLINK_PATH_KEY] = linkPath; + } + const std::string sysroot = + lg->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT"); + if (!sysroot.empty()) { + result[kSYSROOT_KEY] = sysroot; + } + } + + std::set languages; + std::map languageDataMap; + if (type == cmStateEnums::INTERFACE_LIBRARY) { + // INTERFACE_LIBRARY targets do not create all the data structures + // associated with regular targets. If properties are explicitly specified + // for files in INTERFACE_SOURCES then we can get them through the Makefile + // rather than the target. + for (auto file : target->Makefile->GetSourceFiles()) { + const std::string& language = file->GetLanguage(); + if (!language.empty()) { + languages.insert(language); + } + } + } else { + target->GetLanguages(languages, config); + } + + for (std::string const& lang : languages) { + LanguageData& ld = languageDataMap[lang]; + ld.Language = lang; + lg->GetTargetCompileFlags(target, config, lang, ld.Flags); + std::set defines; + lg->GetTargetDefines(target, config, lang, defines); + ld.SetDefines(defines); + std::vector includePathList; + lg->GetIncludeDirectories(includePathList, target, lang, config, true); + for (std::string const& i : includePathList) { + ld.IncludePathList.push_back( + std::make_pair(i, target->IsSystemIncludeDirectory(i, config, lang))); + } + } + + if (target->Target->GetProperty("INTERFACE_SOURCES") != nullptr) { + // Create an entry in the languageDataMap for interface sources. + CreateInterfaceSourcesEntry(lg, target, config, languageDataMap); + } + + Json::Value sourceGroupsValue = + DumpSourceFilesList(target, config, languageDataMap); + if (!sourceGroupsValue.empty()) { + result[kFILE_GROUPS_KEY] = sourceGroupsValue; + } + + return result; +} + +static Json::Value DumpTargetsList( + const std::vector& generators, const std::string& config) +{ + Json::Value result = Json::arrayValue; + + std::vector targetList; + for (auto const& lgIt : generators) { + const auto& list = lgIt->GetGeneratorTargets(); + targetList.insert(targetList.end(), list.begin(), list.end()); + } + std::sort(targetList.begin(), targetList.end()); + + for (cmGeneratorTarget* target : targetList) { + Json::Value tmp = DumpTarget(target, config); + if (!tmp.isNull()) { + result.append(tmp); + } + } + + return result; +} + +static Json::Value DumpProjectList(const cmake* cm, std::string const& config) +{ + Json::Value result = Json::arrayValue; + + auto globalGen = cm->GetGlobalGenerator(); + + for (auto const& projectIt : globalGen->GetProjectMap()) { + Json::Value pObj = Json::objectValue; + pObj[kNAME_KEY] = projectIt.first; + + // All Projects must have at least one local generator + assert(!projectIt.second.empty()); + const cmLocalGenerator* lg = projectIt.second.at(0); + + // Project structure information: + const cmMakefile* mf = lg->GetMakefile(); + auto minVersion = mf->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"); + pObj[kMINIMUM_CMAKE_VERSION] = minVersion ? minVersion : ""; + pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory(); + pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory(); + pObj[kTARGETS_KEY] = DumpTargetsList(projectIt.second, config); + + // For a project-level install rule it might be defined in any of its + // associated generators. + bool hasInstallRule = false; + for (const auto generator : projectIt.second) { + hasInstallRule = + generator->GetMakefile()->GetInstallGenerators().empty() == false; + + if (hasInstallRule) { + break; + } + } + + pObj[kHAS_INSTALL_RULE] = hasInstallRule; + + result.append(pObj); + } + + return result; +} + +static Json::Value DumpConfiguration(const cmake* cm, + const std::string& config) +{ + Json::Value result = Json::objectValue; + result[kNAME_KEY] = config; + + result[kPROJECTS_KEY] = DumpProjectList(cm, config); + + return result; +} + +static Json::Value DumpConfigurationsList(const cmake* cm) +{ + Json::Value result = Json::arrayValue; + + for (std::string const& c : getConfigurations(cm)) { + result.append(DumpConfiguration(cm, c)); + } + + return result; +} + +static Json::Value DumpCodeModel(const cmake* cm) +{ + Json::Value result = Json::objectValue; + result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm); + return result; +} diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 266d05c..5d29bf8 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -5,38 +5,19 @@ #include "cmAlgorithms.h" #include "cmExternalMakefileProjectGenerator.h" #include "cmFileMonitor.h" -#include "cmGeneratorExpression.h" -#include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" -#include "cmInstallGenerator.h" -#include "cmInstallTargetGenerator.h" -#include "cmLinkLineComputer.h" -#include "cmLocalGenerator.h" -#include "cmMakefile.h" -#include "cmProperty.h" #include "cmServer.h" #include "cmServerDictionary.h" -#include "cmSourceFile.h" #include "cmState.h" -#include "cmStateDirectory.h" -#include "cmStateSnapshot.h" -#include "cmStateTypes.h" #include "cmSystemTools.h" -#include "cmTarget.h" -#include "cmTest.h" #include "cm_uv.h" #include "cmake.h" #include #include -#include #include -#include -#include #include -#include #include -#include #include // Get rid of some windows macros: @@ -44,38 +25,6 @@ namespace { -std::vector getConfigurations(const cmake* cm) -{ - std::vector configurations; - auto makefiles = cm->GetGlobalGenerator()->GetMakefiles(); - if (makefiles.empty()) { - return configurations; - } - - makefiles[0]->GetConfigurations(configurations); - if (configurations.empty()) { - configurations.push_back(""); - } - return configurations; -} - -bool hasString(const Json::Value& v, const std::string& s) -{ - return !v.isNull() && - std::any_of(v.begin(), v.end(), - [s](const Json::Value& i) { return i.asString() == s; }); -} - -template -Json::Value fromStringList(const T& in) -{ - Json::Value result = Json::arrayValue; - for (std::string const& i : in) { - result.append(i); - } - return result; -} - std::vector toStringList(const Json::Value& in) { std::vector result; @@ -85,51 +34,10 @@ std::vector toStringList(const Json::Value& in) return result; } -void getCMakeInputs(const cmGlobalGenerator* gg, const std::string& sourceDir, - const std::string& buildDir, - std::vector* internalFiles, - std::vector* explicitFiles, - std::vector* tmpFiles) -{ - const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/'; - std::vector const& makefiles = gg->GetMakefiles(); - for (cmMakefile const* mf : makefiles) { - for (std::string const& lf : mf->GetListFiles()) { - - const std::string startOfFile = lf.substr(0, cmakeRootDir.size()); - const bool isInternal = (startOfFile == cmakeRootDir); - const bool isTemporary = !isInternal && (lf.find(buildDir + '/') == 0); - - std::string toAdd = lf; - if (!sourceDir.empty()) { - const std::string& relative = - cmSystemTools::RelativePath(sourceDir, lf); - if (toAdd.size() > relative.size()) { - toAdd = relative; - } - } - - if (isInternal) { - if (internalFiles) { - internalFiles->push_back(std::move(toAdd)); - } - } else { - if (isTemporary) { - if (tmpFiles) { - tmpFiles->push_back(std::move(toAdd)); - } - } else { - if (explicitFiles) { - explicitFiles->push_back(std::move(toAdd)); - } - } - } - } - } -} - } // namespace +#include "cmJsonObjects.cxx" + cmServerRequest::cmServerRequest(cmServer* server, cmConnection* connection, const std::string& t, const std::string& c, const Json::Value& d) @@ -550,41 +458,6 @@ cmServerResponse cmServerProtocol1::ProcessCache( return request.Reply(result); } -static Json::Value DumpCMakeInputs(const cmake* cm) -{ - const cmGlobalGenerator* gg = cm->GetGlobalGenerator(); - const std::string& buildDir = cm->GetHomeOutputDirectory(); - const std::string& sourceDir = cm->GetHomeDirectory(); - - std::vector internalFiles; - std::vector explicitFiles; - std::vector 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); - - return array; -} - cmServerResponse cmServerProtocol1::ProcessCMakeInputs( const cmServerRequest& request) { @@ -603,678 +476,6 @@ cmServerResponse cmServerProtocol1::ProcessCMakeInputs( return request.Reply(result); } -const std::string kInterfaceSourcesLanguageDataKey = - "INTERFACE_SOURCES_LD_KEY"; -class LanguageData -{ -public: - bool operator==(const LanguageData& other) const; - - void SetDefines(const std::set& defines); - - bool IsGenerated = false; - std::string Language; - std::string Flags; - std::vector Defines; - std::vector> IncludePathList; -}; - -bool LanguageData::operator==(const LanguageData& other) const -{ - return Language == other.Language && Defines == other.Defines && - Flags == other.Flags && IncludePathList == other.IncludePathList && - IsGenerated == other.IsGenerated; -} - -void LanguageData::SetDefines(const std::set& defines) -{ - std::vector result; - result.reserve(defines.size()); - for (std::string const& i : defines) { - result.push_back(i); - } - std::sort(result.begin(), result.end()); - Defines = std::move(result); -} - -struct FileGroupSources -{ - bool IsInterfaceSources; - std::vector Files; -}; - -namespace std { - -template <> -struct hash -{ - std::size_t operator()(const LanguageData& in) const - { - using std::hash; - size_t result = - hash()(in.Language) ^ hash()(in.Flags); - for (auto const& i : in.IncludePathList) { - result = result ^ - (hash()(i.first) ^ - (i.second ? std::numeric_limits::max() : 0)); - } - for (auto const& i : in.Defines) { - result = result ^ hash()(i); - } - result = - result ^ (in.IsGenerated ? std::numeric_limits::max() : 0); - return result; - } -}; - -} // namespace std - -static Json::Value DumpSourceFileGroup(const LanguageData& data, - bool isInterfaceSource, - const std::vector& files, - const std::string& baseDir) -{ - Json::Value result = Json::objectValue; - - if (isInterfaceSource) { - result[kIS_INTERFACE_SOURCES_KEY] = true; - } - if (!data.Language.empty()) { - result[kLANGUAGE_KEY] = data.Language; - } - if (!data.Flags.empty()) { - result[kCOMPILE_FLAGS_KEY] = data.Flags; - } - if (!data.IncludePathList.empty()) { - Json::Value includes = Json::arrayValue; - for (auto const& i : data.IncludePathList) { - Json::Value tmp = Json::objectValue; - tmp[kPATH_KEY] = i.first; - if (i.second) { - tmp[kIS_SYSTEM_KEY] = i.second; - } - includes.append(tmp); - } - result[kINCLUDE_PATH_KEY] = includes; - } - if (!data.Defines.empty()) { - result[kDEFINES_KEY] = fromStringList(data.Defines); - } - - result[kIS_GENERATED_KEY] = data.IsGenerated; - - Json::Value sourcesValue = Json::arrayValue; - for (auto const& i : files) { - const std::string relPath = cmSystemTools::RelativePath(baseDir, i); - sourcesValue.append(relPath.size() < i.size() ? relPath : i); - } - - result[kSOURCES_KEY] = sourcesValue; - return result; -} - -static void PopulateFileGroupData( - cmGeneratorTarget* target, bool isInterfaceSources, - const std::vector& files, const std::string& config, - const std::map& languageDataMap, - std::unordered_map& fileGroups) -{ - for (cmSourceFile* file : files) { - LanguageData fileData; - fileData.Language = file->GetLanguage(); - if (!fileData.Language.empty() || isInterfaceSources) { - const LanguageData& ld = isInterfaceSources - ? languageDataMap.at(kInterfaceSourcesLanguageDataKey) - : languageDataMap.at(fileData.Language); - cmLocalGenerator* lg = target->GetLocalGenerator(); - cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target, - fileData.Language); - - std::string compileFlags = ld.Flags; - const std::string COMPILE_FLAGS("COMPILE_FLAGS"); - if (const char* cflags = file->GetProperty(COMPILE_FLAGS)) { - lg->AppendFlags(compileFlags, - genexInterpreter.Evaluate(cflags, COMPILE_FLAGS)); - } - const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); - if (const char* coptions = file->GetProperty(COMPILE_OPTIONS)) { - lg->AppendCompileOptions( - compileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS)); - } - fileData.Flags = compileFlags; - - // Add include directories from source file properties. - std::vector includes; - - const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES"); - if (const char* cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) { - const std::string& evaluatedIncludes = - genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES); - lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file); - - for (const auto& include : includes) { - // INTERFACE_LIBRARY targets do not support the - // IsSystemIncludeDirectory call so just set it to false. - const bool isSystemInclude = isInterfaceSources - ? false - : target->IsSystemIncludeDirectory(include, config, - fileData.Language); - fileData.IncludePathList.push_back( - std::make_pair(include, isSystemInclude)); - } - } - - fileData.IncludePathList.insert(fileData.IncludePathList.end(), - ld.IncludePathList.begin(), - ld.IncludePathList.end()); - - const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); - std::set defines; - if (const char* defs = file->GetProperty(COMPILE_DEFINITIONS)) { - lg->AppendDefines( - defines, genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS)); - } - - const std::string defPropName = - "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config); - if (const char* config_defs = file->GetProperty(defPropName)) { - lg->AppendDefines( - defines, - genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS)); - } - - defines.insert(ld.Defines.begin(), ld.Defines.end()); - - fileData.SetDefines(defines); - } - - fileData.IsGenerated = file->GetPropertyAsBool("GENERATED"); - FileGroupSources& groupFileList = fileGroups[fileData]; - groupFileList.IsInterfaceSources = isInterfaceSources; - groupFileList.Files.push_back(file->GetFullPath()); - } -} - -static Json::Value DumpSourceFilesList( - cmGeneratorTarget* target, const std::string& config, - const std::map& languageDataMap) -{ - const cmStateEnums::TargetType type = target->GetType(); - std::unordered_map fileGroups; - - // Collect sourcefile groups: - - std::vector files; - if (type == cmStateEnums::INTERFACE_LIBRARY) { - // INTERFACE_LIBRARY targets do not create all the data structures - // associated with regular targets. If properties are explicitly specified - // for files in INTERFACE_SOURCES then we can get them through the Makefile - // rather than the target. - files = target->Makefile->GetSourceFiles(); - } else { - target->GetSourceFiles(files, config); - PopulateFileGroupData(target, false /* isInterfaceSources */, files, - config, languageDataMap, fileGroups); - } - - // Collect interface sourcefile groups: - - auto targetProp = target->Target->GetProperty("INTERFACE_SOURCES"); - if (targetProp != nullptr) { - cmGeneratorExpressionInterpreter genexInterpreter( - target->GetLocalGenerator(), config, target); - - auto evaluatedSources = cmsys::SystemTools::SplitString( - genexInterpreter.Evaluate(targetProp, "INTERFACE_SOURCES"), ';'); - - std::map filesMap; - for (auto file : files) { - filesMap[file->GetFullPath()] = file; - } - - std::vector interfaceSourceFiles; - for (const std::string& interfaceSourceFilePath : evaluatedSources) { - auto entry = filesMap.find(interfaceSourceFilePath); - if (entry != filesMap.end()) { - // use what we have since it has all the associated properties - interfaceSourceFiles.push_back(entry->second); - } else { - interfaceSourceFiles.push_back( - new cmSourceFile(target->Makefile, interfaceSourceFilePath)); - } - } - - PopulateFileGroupData(target, true /* isInterfaceSources */, - interfaceSourceFiles, config, languageDataMap, - fileGroups); - } - - const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory(); - Json::Value result = Json::arrayValue; - for (auto const& it : fileGroups) { - Json::Value group = DumpSourceFileGroup( - it.first, it.second.IsInterfaceSources, it.second.Files, baseDir); - if (!group.isNull()) { - result.append(group); - } - } - - return result; -} - -static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo, - const std::string& config) -{ - Json::Value result = Json::objectValue; - result[kCTEST_NAME] = testInfo->GetName(); - - // Concat command entries together. After the first should be the arguments - // for the command - std::string command; - for (auto const& cmd : testInfo->GetCommand()) { - command.append(cmd); - command.append(" "); - } - - // Remove any config specific variables from the output. - cmGeneratorExpression ge; - auto cge = ge.Parse(command); - const std::string& processed = cge->Evaluate(lg, config); - result[kCTEST_COMMAND] = processed; - - // Build up the list of properties that may have been specified - Json::Value properties = Json::arrayValue; - for (auto& prop : testInfo->GetProperties()) { - Json::Value entry = Json::objectValue; - entry[kKEY_KEY] = prop.first; - - // Remove config variables from the value too. - auto cge_value = ge.Parse(prop.second.GetValue()); - const std::string& processed_value = cge_value->Evaluate(lg, config); - entry[kVALUE_KEY] = processed_value; - properties.append(entry); - } - result[kPROPERTIES_KEY] = properties; - - return result; -} - -static void DumpMakefileTests(cmLocalGenerator* lg, const std::string& config, - Json::Value* result) -{ - auto mf = lg->GetMakefile(); - std::vector tests; - mf->GetTests(config, tests); - for (auto test : tests) { - Json::Value tmp = DumpCTestInfo(lg, test, config); - if (!tmp.isNull()) { - result->append(tmp); - } - } -} - -static Json::Value DumpCTestProjectList(const cmake* cm, - std::string const& config) -{ - Json::Value result = Json::arrayValue; - - auto globalGen = cm->GetGlobalGenerator(); - - for (const auto& projectIt : globalGen->GetProjectMap()) { - Json::Value pObj = Json::objectValue; - pObj[kNAME_KEY] = projectIt.first; - - Json::Value tests = Json::arrayValue; - - // Gather tests for every generator - for (const auto& lg : projectIt.second) { - // Make sure they're generated. - lg->GenerateTestFiles(); - DumpMakefileTests(lg, config, &tests); - } - - pObj[kCTEST_INFO] = tests; - - result.append(pObj); - } - - return result; -} - -static Json::Value DumpCTestConfiguration(const cmake* cm, - const std::string& config) -{ - Json::Value result = Json::objectValue; - result[kNAME_KEY] = config; - - result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config); - - return result; -} - -static Json::Value DumpCTestConfigurationsList(const cmake* cm) -{ - Json::Value result = Json::arrayValue; - - for (const std::string& c : getConfigurations(cm)) { - result.append(DumpCTestConfiguration(cm, c)); - } - - return result; -} - -static Json::Value DumpCTestInfo(const cmake* cm) -{ - Json::Value result = Json::objectValue; - result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm); - return result; -} - -static void GetTargetProperty( - cmGeneratorExpressionInterpreter& genexInterpreter, - cmGeneratorTarget* target, const char* propertyName, - std::vector& propertyValue) -{ - auto targetProp = target->Target->GetProperty(propertyName); - if (targetProp != nullptr) { - propertyValue = cmsys::SystemTools::SplitString( - genexInterpreter.Evaluate(targetProp, propertyName), ';'); - } -} - -static void CreateInterfaceSourcesEntry( - cmLocalGenerator* lg, cmGeneratorTarget* target, const std::string& config, - std::map& languageDataMap) -{ - LanguageData& ld = languageDataMap[kInterfaceSourcesLanguageDataKey]; - ld.Language = ""; - - cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target); - std::vector propertyValue; - GetTargetProperty(genexInterpreter, target, "INTERFACE_INCLUDE_DIRECTORIES", - propertyValue); - for (std::string const& i : propertyValue) { - ld.IncludePathList.push_back( - std::make_pair(i, false /* isSystemInclude */)); - } - - propertyValue.clear(); - GetTargetProperty(genexInterpreter, target, - "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", propertyValue); - for (std::string const& i : propertyValue) { - ld.IncludePathList.push_back( - std::make_pair(i, true /* isSystemInclude */)); - } - - propertyValue.clear(); - GetTargetProperty(genexInterpreter, target, "INTERFACE_COMPILE_OPTIONS", - propertyValue); - for (const auto& s : propertyValue) { - ld.Flags += " " + s; - } - - propertyValue.clear(); - GetTargetProperty(genexInterpreter, target, "INTERFACE_COMPILE_DEFINITIONS", - propertyValue); - if (!propertyValue.empty()) { - std::set defines(propertyValue.begin(), propertyValue.end()); - ld.SetDefines(defines); - } -} - -static Json::Value DumpTarget(cmGeneratorTarget* target, - const std::string& config) -{ - cmLocalGenerator* lg = target->GetLocalGenerator(); - const cmState* state = lg->GetState(); - - const cmStateEnums::TargetType type = target->GetType(); - const std::string typeName = state->GetTargetTypeName(type); - - Json::Value ttl = Json::arrayValue; - ttl.append("EXECUTABLE"); - ttl.append("STATIC_LIBRARY"); - ttl.append("SHARED_LIBRARY"); - ttl.append("MODULE_LIBRARY"); - ttl.append("OBJECT_LIBRARY"); - ttl.append("UTILITY"); - ttl.append("INTERFACE_LIBRARY"); - - if (!hasString(ttl, typeName) || target->IsImported()) { - return Json::Value(); - } - - Json::Value result = Json::objectValue; - result[kNAME_KEY] = target->GetName(); - result[kIS_GENERATOR_PROVIDED_KEY] = - target->Target->GetIsGeneratorProvided(); - result[kTYPE_KEY] = typeName; - result[kSOURCE_DIRECTORY_KEY] = lg->GetCurrentSourceDirectory(); - result[kBUILD_DIRECTORY_KEY] = lg->GetCurrentBinaryDirectory(); - result[kFULL_NAME_KEY] = target->GetFullName(config); - - if (target->Target->GetHaveInstallRule()) { - result[kHAS_INSTALL_RULE] = true; - - Json::Value installPaths = Json::arrayValue; - auto targetGenerators = target->Makefile->GetInstallGenerators(); - for (auto installGenerator : targetGenerators) { - auto installTargetGenerator = - dynamic_cast(installGenerator); - if (installTargetGenerator != nullptr && - installTargetGenerator->GetTarget()->Target == target->Target) { - auto dest = installTargetGenerator->GetDestination(config); - - std::string installPath; - if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) { - installPath = dest; - } else { - std::string installPrefix = - target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); - installPath = installPrefix + '/' + dest; - } - - installPaths.append(installPath); - } - } - - result[kINSTALL_PATHS] = installPaths; - } - - if (target->HaveWellDefinedOutputFiles()) { - Json::Value artifacts = Json::arrayValue; - artifacts.append( - target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact)); - if (target->IsDLLPlatform()) { - artifacts.append( - target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact)); - const cmGeneratorTarget::OutputInfo* output = - target->GetOutputInfo(config); - if (output && !output->PdbDir.empty()) { - artifacts.append(output->PdbDir + '/' + target->GetPDBName(config)); - } - } - result[kARTIFACTS_KEY] = artifacts; - - result[kLINKER_LANGUAGE_KEY] = target->GetLinkerLanguage(config); - - std::string linkLibs; - std::string linkFlags; - std::string linkLanguageFlags; - std::string frameworkPath; - std::string linkPath; - cmLinkLineComputer linkLineComputer(lg, - lg->GetStateSnapshot().GetDirectory()); - lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags, - linkFlags, frameworkPath, linkPath, target); - - linkLibs = cmSystemTools::TrimWhitespace(linkLibs); - linkFlags = cmSystemTools::TrimWhitespace(linkFlags); - linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags); - frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath); - linkPath = cmSystemTools::TrimWhitespace(linkPath); - - if (!cmSystemTools::TrimWhitespace(linkLibs).empty()) { - result[kLINK_LIBRARIES_KEY] = linkLibs; - } - if (!cmSystemTools::TrimWhitespace(linkFlags).empty()) { - result[kLINK_FLAGS_KEY] = linkFlags; - } - if (!cmSystemTools::TrimWhitespace(linkLanguageFlags).empty()) { - result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags; - } - if (!frameworkPath.empty()) { - result[kFRAMEWORK_PATH_KEY] = frameworkPath; - } - if (!linkPath.empty()) { - result[kLINK_PATH_KEY] = linkPath; - } - const std::string sysroot = - lg->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT"); - if (!sysroot.empty()) { - result[kSYSROOT_KEY] = sysroot; - } - } - - std::set languages; - std::map languageDataMap; - if (type == cmStateEnums::INTERFACE_LIBRARY) { - // INTERFACE_LIBRARY targets do not create all the data structures - // associated with regular targets. If properties are explicitly specified - // for files in INTERFACE_SOURCES then we can get them through the Makefile - // rather than the target. - for (auto file : target->Makefile->GetSourceFiles()) { - const std::string& language = file->GetLanguage(); - if (!language.empty()) { - languages.insert(language); - } - } - } else { - target->GetLanguages(languages, config); - } - - for (std::string const& lang : languages) { - LanguageData& ld = languageDataMap[lang]; - ld.Language = lang; - lg->GetTargetCompileFlags(target, config, lang, ld.Flags); - std::set defines; - lg->GetTargetDefines(target, config, lang, defines); - ld.SetDefines(defines); - std::vector includePathList; - lg->GetIncludeDirectories(includePathList, target, lang, config, true); - for (std::string const& i : includePathList) { - ld.IncludePathList.push_back( - std::make_pair(i, target->IsSystemIncludeDirectory(i, config, lang))); - } - } - - if (target->Target->GetProperty("INTERFACE_SOURCES") != nullptr) { - // Create an entry in the languageDataMap for interface sources. - CreateInterfaceSourcesEntry(lg, target, config, languageDataMap); - } - - Json::Value sourceGroupsValue = - DumpSourceFilesList(target, config, languageDataMap); - if (!sourceGroupsValue.empty()) { - result[kFILE_GROUPS_KEY] = sourceGroupsValue; - } - - return result; -} - -static Json::Value DumpTargetsList( - const std::vector& generators, const std::string& config) -{ - Json::Value result = Json::arrayValue; - - std::vector targetList; - for (auto const& lgIt : generators) { - const auto& list = lgIt->GetGeneratorTargets(); - targetList.insert(targetList.end(), list.begin(), list.end()); - } - std::sort(targetList.begin(), targetList.end()); - - for (cmGeneratorTarget* target : targetList) { - Json::Value tmp = DumpTarget(target, config); - if (!tmp.isNull()) { - result.append(tmp); - } - } - - return result; -} - -static Json::Value DumpProjectList(const cmake* cm, std::string const& config) -{ - Json::Value result = Json::arrayValue; - - auto globalGen = cm->GetGlobalGenerator(); - - for (auto const& projectIt : globalGen->GetProjectMap()) { - Json::Value pObj = Json::objectValue; - pObj[kNAME_KEY] = projectIt.first; - - // All Projects must have at least one local generator - assert(!projectIt.second.empty()); - const cmLocalGenerator* lg = projectIt.second.at(0); - - // Project structure information: - const cmMakefile* mf = lg->GetMakefile(); - auto minVersion = mf->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"); - pObj[kMINIMUM_CMAKE_VERSION] = minVersion ? minVersion : ""; - pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory(); - pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory(); - pObj[kTARGETS_KEY] = DumpTargetsList(projectIt.second, config); - - // For a project-level install rule it might be defined in any of its - // associated generators. - bool hasInstallRule = false; - for (const auto generator : projectIt.second) { - hasInstallRule = - generator->GetMakefile()->GetInstallGenerators().empty() == false; - - if (hasInstallRule) { - break; - } - } - - pObj[kHAS_INSTALL_RULE] = hasInstallRule; - - result.append(pObj); - } - - return result; -} - -static Json::Value DumpConfiguration(const cmake* cm, - const std::string& config) -{ - Json::Value result = Json::objectValue; - result[kNAME_KEY] = config; - - result[kPROJECTS_KEY] = DumpProjectList(cm, config); - - return result; -} - -static Json::Value DumpConfigurationsList(const cmake* cm) -{ - Json::Value result = Json::arrayValue; - - for (std::string const& c : getConfigurations(cm)) { - result.append(DumpConfiguration(cm, c)); - } - - return result; -} - -static Json::Value DumpCodeModel(const cmake* cm) -{ - Json::Value result = Json::objectValue; - result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm); - return result; -} - cmServerResponse cmServerProtocol1::ProcessCodeModel( const cmServerRequest& request) { -- cgit v0.12 From b48165346f7dfcd025beca743abf2eaf849bf17d Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 21 Sep 2018 11:21:37 -0400 Subject: server: Split json dictionary into separate header Move dictionary entries used by the json object generation code into a separate header. These are distinct from the server-only entries used in the protocol implementation. --- Source/cmJsonObjectDictionary.h | 46 +++++++++++++++++++++++++++++++++++++++++ Source/cmServer.cxx | 1 + Source/cmServerDictionary.h | 38 ---------------------------------- Source/cmServerProtocol.cxx | 1 + 4 files changed, 48 insertions(+), 38 deletions(-) create mode 100644 Source/cmJsonObjectDictionary.h diff --git a/Source/cmJsonObjectDictionary.h b/Source/cmJsonObjectDictionary.h new file mode 100644 index 0000000..a4d41f3 --- /dev/null +++ b/Source/cmJsonObjectDictionary.h @@ -0,0 +1,46 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include + +// Vocabulary: + +static const std::string kARTIFACTS_KEY = "artifacts"; +static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory"; +static const std::string kCOMPILE_FLAGS_KEY = "compileFlags"; +static const std::string kCONFIGURATIONS_KEY = "configurations"; +static const std::string kDEFINES_KEY = "defines"; +static const std::string kFILE_GROUPS_KEY = "fileGroups"; +static const std::string kFRAMEWORK_PATH_KEY = "frameworkPath"; +static const std::string kFULL_NAME_KEY = "fullName"; +static const std::string kINCLUDE_PATH_KEY = "includePath"; +static const std::string kIS_CMAKE_KEY = "isCMake"; +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 kKEY_KEY = "key"; +static const std::string kLANGUAGE_KEY = "language"; +static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage"; +static const std::string kLINK_FLAGS_KEY = "linkFlags"; +static const std::string kLINK_LANGUAGE_FLAGS_KEY = "linkLanguageFlags"; +static const std::string kLINK_LIBRARIES_KEY = "linkLibraries"; +static const std::string kLINK_PATH_KEY = "linkPath"; +static const std::string kNAME_KEY = "name"; +static const std::string kPATH_KEY = "path"; +static const std::string kPROJECTS_KEY = "projects"; +static const std::string kPROPERTIES_KEY = "properties"; +static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory"; +static const std::string kSOURCES_KEY = "sources"; +static const std::string kSYSROOT_KEY = "sysroot"; +static const std::string kTARGETS_KEY = "targets"; +static const std::string kTYPE_KEY = "type"; +static const std::string kVALUE_KEY = "value"; +static const std::string kHAS_INSTALL_RULE = "hasInstallRule"; +static const std::string kINSTALL_PATHS = "installPaths"; +static const std::string kCTEST_NAME = "ctestName"; +static const std::string kCTEST_COMMAND = "ctestCommand"; +static const std::string kCTEST_INFO = "ctestInfo"; +static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion"; +static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided"; +static const std::string kIS_INTERFACE_SOURCES_KEY = "isInterfaceSources"; diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index 1b04ca2..f15a14a 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -5,6 +5,7 @@ #include "cmAlgorithms.h" #include "cmConnection.h" #include "cmFileMonitor.h" +#include "cmJsonObjectDictionary.h" #include "cmServerDictionary.h" #include "cmServerProtocol.h" #include "cmSystemTools.h" diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h index ebf16eb..961e4b7 100644 --- a/Source/cmServerDictionary.h +++ b/Source/cmServerDictionary.h @@ -25,78 +25,40 @@ static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings"; static const std::string kSIGNAL_TYPE = "signal"; static const std::string kCTEST_INFO_TYPE = "ctestInfo"; -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 kCACHE_KEY = "cache"; 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"; static const std::string kDEBUG_OUTPUT_KEY = "debugOutput"; -static const std::string kDEFINES_KEY = "defines"; static const std::string kERROR_MESSAGE_KEY = "errorMessage"; static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator"; -static const std::string kFILE_GROUPS_KEY = "fileGroups"; -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 kKEY_KEY = "key"; static const std::string kKEYS_KEY = "keys"; -static const std::string kLANGUAGE_KEY = "language"; -static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage"; -static const std::string kLINK_FLAGS_KEY = "linkFlags"; -static const std::string kLINK_LANGUAGE_FLAGS_KEY = "linkLanguageFlags"; -static const std::string kLINK_LIBRARIES_KEY = "linkLibraries"; -static const std::string kLINK_PATH_KEY = "linkPath"; static const std::string kMAJOR_KEY = "major"; static const std::string kMESSAGE_KEY = "message"; static const std::string kMINOR_KEY = "minor"; -static const std::string kNAME_KEY = "name"; -static const std::string kPATH_KEY = "path"; static const std::string kPLATFORM_KEY = "platform"; static const std::string kPROGRESS_CURRENT_KEY = "progressCurrent"; static const std::string kPROGRESS_MAXIMUM_KEY = "progressMaximum"; static const std::string kPROGRESS_MESSAGE_KEY = "progressMessage"; static const std::string kPROGRESS_MINIMUM_KEY = "progressMinimum"; -static const std::string kPROJECTS_KEY = "projects"; -static const std::string kPROPERTIES_KEY = "properties"; static const std::string kPROTOCOL_VERSION_KEY = "protocolVersion"; static const std::string kREPLY_TO_KEY = "inReplyTo"; -static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory"; -static const std::string kSOURCES_KEY = "sources"; static const std::string kSUPPORTED_PROTOCOL_VERSIONS = "supportedProtocolVersions"; -static const std::string kSYSROOT_KEY = "sysroot"; -static const std::string kTARGETS_KEY = "targets"; static const std::string kTITLE_KEY = "title"; static const std::string kTOOLSET_KEY = "toolset"; static const std::string kTRACE_EXPAND_KEY = "traceExpand"; static const std::string kTRACE_KEY = "trace"; -static const std::string kTYPE_KEY = "type"; -static const std::string kVALUE_KEY = "value"; static const std::string kWARN_UNINITIALIZED_KEY = "warnUninitialized"; static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli"; static const std::string kWARN_UNUSED_KEY = "warnUnused"; static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories"; static const std::string kWATCHED_FILES_KEY = "watchedFiles"; -static const std::string kHAS_INSTALL_RULE = "hasInstallRule"; -static const std::string kINSTALL_PATHS = "installPaths"; -static const std::string kCTEST_NAME = "ctestName"; -static const std::string kCTEST_COMMAND = "ctestCommand"; -static const std::string kCTEST_INFO = "ctestInfo"; -static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion"; -static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided"; -static const std::string kIS_INTERFACE_SOURCES_KEY = "isInterfaceSources"; static const std::string kSTART_MAGIC = "[== \"CMake Server\" ==["; static const std::string kEND_MAGIC = "]== \"CMake Server\" ==]"; diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 5d29bf8..6a09776 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -6,6 +6,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmFileMonitor.h" #include "cmGlobalGenerator.h" +#include "cmJsonObjectDictionary.h" #include "cmServer.h" #include "cmServerDictionary.h" #include "cmState.h" -- cgit v0.12 From 72b4c2c48ae7dfd8c2813018c72ed0d2e6bb907a Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 21 Sep 2018 11:11:36 -0400 Subject: server: Compile json object generation source separately Declare entry points in a dedicated header and compile the source separately instead of including it in the server implementation. --- Source/CMakeLists.txt | 3 +++ Source/cmJsonObjects.cxx | 28 ++++++++++++++++------------ Source/cmJsonObjects.h | 27 +++++++++++++++++++++++++++ Source/cmServerProtocol.cxx | 12 ++++++------ 4 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 Source/cmJsonObjects.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 628cc6f..bfddbc6 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -1047,6 +1047,9 @@ target_link_libraries(cmake CMakeLib) add_library(CMakeServerLib cmConnection.h cmConnection.cxx cmFileMonitor.cxx cmFileMonitor.h + cmJsonObjectDictionary.h + cmJsonObjects.h + cmJsonObjects.cxx cmPipeConnection.cxx cmPipeConnection.h cmServer.cxx cmServer.h cmServerConnection.cxx cmServerConnection.h diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index b534471..a7db75f 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -1,11 +1,14 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmJsonObjects.h" // IWYU pragma: keep #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmInstallGenerator.h" #include "cmInstallTargetGenerator.h" +#include "cmJsonObjectDictionary.h" +#include "cmJsonObjects.h" #include "cmLinkLineComputer.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" @@ -66,11 +69,14 @@ Json::Value fromStringList(const T& in) return result; } -void getCMakeInputs(const cmGlobalGenerator* gg, const std::string& sourceDir, - const std::string& buildDir, - std::vector* internalFiles, - std::vector* explicitFiles, - std::vector* tmpFiles) +} // namespace + +void cmGetCMakeInputs(const cmGlobalGenerator* gg, + const std::string& sourceDir, + const std::string& buildDir, + std::vector* internalFiles, + std::vector* explicitFiles, + std::vector* tmpFiles) { const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/'; std::vector const& makefiles = gg->GetMakefiles(); @@ -109,9 +115,7 @@ void getCMakeInputs(const cmGlobalGenerator* gg, const std::string& sourceDir, } } -} // namespace - -static Json::Value DumpCMakeInputs(const cmake* cm) +Json::Value cmDumpCMakeInputs(const cmake* cm) { const cmGlobalGenerator* gg = cm->GetGlobalGenerator(); const std::string& buildDir = cm->GetHomeOutputDirectory(); @@ -120,8 +124,8 @@ static Json::Value DumpCMakeInputs(const cmake* cm) std::vector internalFiles; std::vector explicitFiles; std::vector tmpFiles; - getCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles, - &tmpFiles); + cmGetCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles, + &tmpFiles); Json::Value array = Json::arrayValue; @@ -506,7 +510,7 @@ static Json::Value DumpCTestConfigurationsList(const cmake* cm) return result; } -static Json::Value DumpCTestInfo(const cmake* cm) +Json::Value cmDumpCTestInfo(const cmake* cm) { Json::Value result = Json::objectValue; result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm); @@ -811,7 +815,7 @@ static Json::Value DumpConfigurationsList(const cmake* cm) return result; } -static Json::Value DumpCodeModel(const cmake* cm) +Json::Value cmDumpCodeModel(const cmake* cm) { Json::Value result = Json::objectValue; result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm); diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h new file mode 100644 index 0000000..cd4da94 --- /dev/null +++ b/Source/cmJsonObjects.h @@ -0,0 +1,27 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmJsonObjects_h +#define cmJsonObjects_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cm_jsoncpp_value.h" + +#include +#include + +class cmake; +class cmGlobalGenerator; + +extern void cmGetCMakeInputs(const cmGlobalGenerator* gg, + const std::string& sourceDir, + const std::string& buildDir, + std::vector* internalFiles, + std::vector* explicitFiles, + std::vector* tmpFiles); + +extern Json::Value cmDumpCodeModel(const cmake* cm); +extern Json::Value cmDumpCTestInfo(const cmake* cm); +extern Json::Value cmDumpCMakeInputs(const cmake* cm); + +#endif diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 6a09776..f75a5ce 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -7,6 +7,7 @@ #include "cmFileMonitor.h" #include "cmGlobalGenerator.h" #include "cmJsonObjectDictionary.h" +#include "cmJsonObjects.h" #include "cmServer.h" #include "cmServerDictionary.h" #include "cmState.h" @@ -37,8 +38,6 @@ std::vector toStringList(const Json::Value& in) } // namespace -#include "cmJsonObjects.cxx" - cmServerRequest::cmServerRequest(cmServer* server, cmConnection* connection, const std::string& t, const std::string& c, const Json::Value& d) @@ -473,7 +472,7 @@ cmServerResponse cmServerProtocol1::ProcessCMakeInputs( Json::Value result = Json::objectValue; result[kSOURCE_DIRECTORY_KEY] = sourceDir; result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir; - result[kBUILD_FILES_KEY] = DumpCMakeInputs(cm); + result[kBUILD_FILES_KEY] = cmDumpCMakeInputs(cm); return request.Reply(result); } @@ -484,7 +483,7 @@ cmServerResponse cmServerProtocol1::ProcessCodeModel( return request.ReportError("No build system was generated yet."); } - return request.Reply(DumpCodeModel(this->CMakeInstance())); + return request.Reply(cmDumpCodeModel(this->CMakeInstance())); } cmServerResponse cmServerProtocol1::ProcessCompute( @@ -601,7 +600,8 @@ cmServerResponse cmServerProtocol1::ProcessConfigure( } std::vector toWatchList; - getCMakeInputs(gg, std::string(), buildDir, nullptr, &toWatchList, nullptr); + cmGetCMakeInputs(gg, std::string(), buildDir, nullptr, &toWatchList, + nullptr); FileMonitor()->MonitorPaths(toWatchList, [this](const std::string& p, int e, int s) { @@ -707,7 +707,7 @@ cmServerResponse cmServerProtocol1::ProcessCTests( return request.ReportError("This instance was not yet computed."); } - return request.Reply(DumpCTestInfo(this->CMakeInstance())); + return request.Reply(cmDumpCTestInfo(this->CMakeInstance())); } cmServerProtocol1::GeneratorInformation::GeneratorInformation( -- cgit v0.12