diff options
author | Ben McMorran <bemcmorr@microsoft.com> | 2021-01-08 00:47:23 (GMT) |
---|---|---|
committer | Ben McMorran <bemcmorr@microsoft.com> | 2021-01-12 19:21:19 (GMT) |
commit | bb069c08571b5dab3488342b03cc4e5705b3a0e2 (patch) | |
tree | 2d96108425b3616681d2ba09d32f58f42339e9d3 /Source | |
parent | 1c9b61c23edb8200400ac77585f94ccd9fe0e58f (diff) | |
download | CMake-bb069c08571b5dab3488342b03cc4e5705b3a0e2.zip CMake-bb069c08571b5dab3488342b03cc4e5705b3a0e2.tar.gz CMake-bb069c08571b5dab3488342b03cc4e5705b3a0e2.tar.bz2 |
cmFileAPI: Add "toolchains" object kind.
Fixes #19514
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmFileAPI.cxx | 63 | ||||
-rw-r--r-- | Source/cmFileAPI.h | 5 | ||||
-rw-r--r-- | Source/cmFileAPIToolchains.cxx | 151 | ||||
-rw-r--r-- | Source/cmFileAPIToolchains.h | 12 |
5 files changed, 233 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c5b67c0..dca94ee 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -268,6 +268,8 @@ set(SRCS cmFileAPICodemodel.h cmFileAPICMakeFiles.cxx cmFileAPICMakeFiles.h + cmFileAPIToolchains.cxx + cmFileAPIToolchains.h cmFileCopier.cxx cmFileCopier.h cmFileInstaller.cxx diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index c2ab2f1..d2a9bec 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -18,6 +18,7 @@ #include "cmFileAPICMakeFiles.h" #include "cmFileAPICache.h" #include "cmFileAPICodemodel.h" +#include "cmFileAPIToolchains.h" #include "cmGlobalGenerator.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -262,6 +263,17 @@ bool cmFileAPI::ReadQuery(std::string const& query, objects.push_back(o); return true; } + if (kindName == ObjectKindName(ObjectKind::Toolchains)) { + Object o; + o.Kind = ObjectKind::Toolchains; + if (verStr == "v1") { + o.Version = 1; + } else { + return false; + } + objects.push_back(o); + return true; + } if (kindName == ObjectKindName(ObjectKind::InternalTest)) { Object o; o.Kind = ObjectKind::InternalTest; @@ -402,6 +414,7 @@ const char* cmFileAPI::ObjectKindName(ObjectKind kind) "codemodel", // "cache", // "cmakeFiles", // + "toolchains", // "__test" // }; return objectKindNames[size_t(kind)]; @@ -435,6 +448,9 @@ Json::Value cmFileAPI::BuildObject(Object const& object) case ObjectKind::CMakeFiles: value = this->BuildCMakeFiles(object); break; + case ObjectKind::Toolchains: + value = this->BuildToolchains(object); + break; case ObjectKind::InternalTest: value = this->BuildInternalTest(object); break; @@ -491,6 +507,8 @@ cmFileAPI::ClientRequest cmFileAPI::BuildClientRequest( r.Kind = ObjectKind::Cache; } else if (kindName == this->ObjectKindName(ObjectKind::CMakeFiles)) { r.Kind = ObjectKind::CMakeFiles; + } else if (kindName == this->ObjectKindName(ObjectKind::Toolchains)) { + r.Kind = ObjectKind::Toolchains; } else if (kindName == this->ObjectKindName(ObjectKind::InternalTest)) { r.Kind = ObjectKind::InternalTest; } else { @@ -518,6 +536,9 @@ cmFileAPI::ClientRequest cmFileAPI::BuildClientRequest( case ObjectKind::CMakeFiles: this->BuildClientRequestCMakeFiles(r, versions); break; + case ObjectKind::Toolchains: + this->BuildClientRequestToolchains(r, versions); + break; case ObjectKind::InternalTest: this->BuildClientRequestInternalTest(r, versions); break; @@ -765,6 +786,40 @@ Json::Value cmFileAPI::BuildCMakeFiles(Object const& object) return cmakeFiles; } +// The "toolchains" object kind. + +static unsigned int const ToolchainsV1Minor = 0; + +void cmFileAPI::BuildClientRequestToolchains( + ClientRequest& r, std::vector<RequestVersion> const& versions) +{ + // Select a known version from those requested. + for (RequestVersion const& v : versions) { + if ((v.Major == 1 && v.Minor <= ToolchainsV1Minor)) { + r.Version = v.Major; + break; + } + } + if (!r.Version) { + r.Error = NoSupportedVersion(versions); + } +} + +Json::Value cmFileAPI::BuildToolchains(Object const& object) +{ + Json::Value toolchains = cmFileAPIToolchainsDump(*this, object.Version); + toolchains["kind"] = this->ObjectKindName(object.Kind); + + Json::Value& version = toolchains["version"]; + if (object.Version == 1) { + version = BuildVersion(1, ToolchainsV1Minor); + } else { + return toolchains; // should be unreachable + } + + return toolchains; +} + // The "__test" object kind is for internal testing of CMake. static unsigned int const InternalTestV1Minor = 3; @@ -828,5 +883,13 @@ Json::Value cmFileAPI::ReportCapabilities() requests.append(std::move(request)); // NOLINT(*) } + { + Json::Value request = Json::objectValue; + request["kind"] = ObjectKindName(ObjectKind::Toolchains); + Json::Value& versions = request["version"] = Json::arrayValue; + versions.append(BuildVersion(1, ToolchainsV1Minor)); + requests.append(std::move(request)); // NOLINT(*) + } + return capabilities; } diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h index 086a92a..22302b4 100644 --- a/Source/cmFileAPI.h +++ b/Source/cmFileAPI.h @@ -56,6 +56,7 @@ private: CodeModel, Cache, CMakeFiles, + Toolchains, InternalTest }; @@ -200,6 +201,10 @@ private: ClientRequest& r, std::vector<RequestVersion> const& versions); Json::Value BuildCMakeFiles(Object const& object); + void BuildClientRequestToolchains( + ClientRequest& r, std::vector<RequestVersion> const& versions); + Json::Value BuildToolchains(Object const& object); + void BuildClientRequestInternalTest( ClientRequest& r, std::vector<RequestVersion> const& versions); Json::Value BuildInternalTest(Object const& object); diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx new file mode 100644 index 0000000..722c114 --- /dev/null +++ b/Source/cmFileAPIToolchains.cxx @@ -0,0 +1,151 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileAPIToolchains.h" + +#include <memory> +#include <string> +#include <vector> + +#include <cm3p/json/value.h> + +#include "cmFileAPI.h" +#include "cmGlobalGenerator.h" +#include "cmMakefile.h" +#include "cmProperty.h" +#include "cmState.h" +#include "cmStringAlgorithms.h" +#include "cmake.h" + +namespace { + +struct ToolchainVariable +{ + std::string ObjectKey; + std::string VariableSuffix; + bool IsList; +}; + +class Toolchains +{ + cmFileAPI& FileAPI; + unsigned long Version; + + static const std::vector<ToolchainVariable> CompilerVariables; + static const std::vector<ToolchainVariable> CompilerImplicitVariables; + static const ToolchainVariable SourceFileExtensionsVariable; + + Json::Value DumpToolchains(); + Json::Value DumpToolchain(std::string const& lang); + Json::Value DumpToolchainVariables( + cmMakefile const* mf, std::string const& lang, + std::vector<ToolchainVariable> const& variables); + void DumpToolchainVariable(cmMakefile const* mf, Json::Value& object, + std::string const& lang, + ToolchainVariable const& variable); + +public: + Toolchains(cmFileAPI& fileAPI, unsigned long version); + Json::Value Dump(); +}; + +const std::vector<ToolchainVariable> Toolchains::CompilerVariables{ + { "path", "COMPILER", false }, + { "id", "COMPILER_ID", false }, + { "version", "COMPILER_VERSION", false }, + { "target", "COMPILER_TARGET", false }, +}; + +const std::vector<ToolchainVariable> Toolchains::CompilerImplicitVariables{ + { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true }, + { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true }, + { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true }, + { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true }, +}; + +const ToolchainVariable Toolchains::SourceFileExtensionsVariable{ + "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true +}; + +Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned long version) + : FileAPI(fileAPI) + , Version(version) +{ + static_cast<void>(this->Version); +} + +Json::Value Toolchains::Dump() +{ + Json::Value toolchains = Json::objectValue; + toolchains["toolchains"] = this->DumpToolchains(); + return toolchains; +} + +Json::Value Toolchains::DumpToolchains() +{ + Json::Value toolchains = Json::arrayValue; + + for (std::string const& lang : + this->FileAPI.GetCMakeInstance()->GetState()->GetEnabledLanguages()) { + toolchains.append(this->DumpToolchain(lang)); + } + + return toolchains; +} + +Json::Value Toolchains::DumpToolchain(std::string const& lang) +{ + const auto& mf = + this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0]; + Json::Value toolchain = Json::objectValue; + toolchain["language"] = lang; + toolchain["compiler"] = + this->DumpToolchainVariables(mf.get(), lang, CompilerVariables); + toolchain["compiler"]["implicit"] = + this->DumpToolchainVariables(mf.get(), lang, CompilerImplicitVariables); + this->DumpToolchainVariable(mf.get(), toolchain, lang, + SourceFileExtensionsVariable); + return toolchain; +} + +Json::Value Toolchains::DumpToolchainVariables( + cmMakefile const* mf, std::string const& lang, + std::vector<ToolchainVariable> const& variables) +{ + Json::Value object = Json::objectValue; + for (const auto& variable : variables) { + this->DumpToolchainVariable(mf, object, lang, variable); + } + return object; +} + +void Toolchains::DumpToolchainVariable(cmMakefile const* mf, + Json::Value& object, + std::string const& lang, + ToolchainVariable const& variable) +{ + std::string const variableName = + cmStrCat("CMAKE_", lang, "_", variable.VariableSuffix); + + if (variable.IsList) { + std::vector<std::string> values; + if (mf->GetDefExpandList(variableName, values)) { + Json::Value jsonArray = Json::arrayValue; + for (std::string const& value : values) { + jsonArray.append(value); + } + object[variable.ObjectKey] = jsonArray; + } + } else { + cmProp def = mf->GetDefinition(variableName); + if (def) { + object[variable.ObjectKey] = *def; + } + } +} +} + +Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned long version) +{ + Toolchains toolchains(fileAPI, version); + return toolchains.Dump(); +} diff --git a/Source/cmFileAPIToolchains.h b/Source/cmFileAPIToolchains.h new file mode 100644 index 0000000..c188807 --- /dev/null +++ b/Source/cmFileAPIToolchains.h @@ -0,0 +1,12 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <cm3p/json/value.h> + +class cmFileAPI; + +extern Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, + unsigned long version); |