cmFileAPIToolchains.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file LICENSE.rst or https://cmake.org/licensing for details. */
  3. #include "cmFileAPIToolchains.h"
  4. #include <memory>
  5. #include <string>
  6. #include <vector>
  7. #include <cm3p/json/value.h>
  8. #include "cmFileAPI.h"
  9. #include "cmGlobalGenerator.h"
  10. #include "cmList.h"
  11. #include "cmMakefile.h"
  12. #include "cmState.h"
  13. #include "cmStringAlgorithms.h"
  14. #include "cmValue.h"
  15. #include "cmake.h"
  16. namespace {
  17. struct ToolchainVariable
  18. {
  19. std::string ObjectKey;
  20. std::string VariableSuffix;
  21. bool IsList;
  22. bool OmitEmpty;
  23. };
  24. class Toolchains
  25. {
  26. cmFileAPI& FileAPI;
  27. unsigned int Version;
  28. Json::Value DumpToolchains();
  29. Json::Value DumpToolchain(std::string const& lang);
  30. Json::Value DumpToolchainVariables(
  31. cmMakefile const* mf, std::string const& lang,
  32. std::vector<ToolchainVariable> const& variables);
  33. void DumpToolchainVariable(cmMakefile const* mf, Json::Value& object,
  34. std::string const& lang,
  35. ToolchainVariable const& variable);
  36. public:
  37. Toolchains(cmFileAPI& fileAPI, unsigned int version);
  38. Json::Value Dump();
  39. };
  40. Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned int version)
  41. : FileAPI(fileAPI)
  42. , Version(version)
  43. {
  44. static_cast<void>(this->Version);
  45. }
  46. Json::Value Toolchains::Dump()
  47. {
  48. Json::Value toolchains = Json::objectValue;
  49. toolchains["toolchains"] = this->DumpToolchains();
  50. return toolchains;
  51. }
  52. Json::Value Toolchains::DumpToolchains()
  53. {
  54. Json::Value toolchains = Json::arrayValue;
  55. for (std::string const& lang :
  56. this->FileAPI.GetCMakeInstance()->GetState()->GetEnabledLanguages()) {
  57. toolchains.append(this->DumpToolchain(lang));
  58. }
  59. return toolchains;
  60. }
  61. Json::Value Toolchains::DumpToolchain(std::string const& lang)
  62. {
  63. static std::vector<ToolchainVariable> const CompilerVariables{
  64. { "path", "COMPILER", false, false },
  65. { "commandFragment", "COMPILER_ARG1", false, true },
  66. { "id", "COMPILER_ID", false, false },
  67. { "version", "COMPILER_VERSION", false, false },
  68. { "target", "COMPILER_TARGET", false, false },
  69. };
  70. static std::vector<ToolchainVariable> const CompilerImplicitVariables{
  71. { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true, false },
  72. { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true, false },
  73. { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true,
  74. false },
  75. { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true, false },
  76. };
  77. static ToolchainVariable const SourceFileExtensionsVariable{
  78. "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true, false
  79. };
  80. auto const& mf =
  81. this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0];
  82. Json::Value toolchain = Json::objectValue;
  83. toolchain["language"] = lang;
  84. toolchain["compiler"] =
  85. this->DumpToolchainVariables(mf.get(), lang, CompilerVariables);
  86. toolchain["compiler"]["implicit"] =
  87. this->DumpToolchainVariables(mf.get(), lang, CompilerImplicitVariables);
  88. this->DumpToolchainVariable(mf.get(), toolchain, lang,
  89. SourceFileExtensionsVariable);
  90. return toolchain;
  91. }
  92. Json::Value Toolchains::DumpToolchainVariables(
  93. cmMakefile const* mf, std::string const& lang,
  94. std::vector<ToolchainVariable> const& variables)
  95. {
  96. Json::Value object = Json::objectValue;
  97. for (auto const& variable : variables) {
  98. this->DumpToolchainVariable(mf, object, lang, variable);
  99. }
  100. return object;
  101. }
  102. void Toolchains::DumpToolchainVariable(cmMakefile const* mf,
  103. Json::Value& object,
  104. std::string const& lang,
  105. ToolchainVariable const& variable)
  106. {
  107. std::string const variableName =
  108. cmStrCat("CMAKE_", lang, '_', variable.VariableSuffix);
  109. if (variable.IsList) {
  110. cmValue data = mf->GetDefinition(variableName);
  111. if (data) {
  112. cmList values(data);
  113. if (!variable.OmitEmpty || !values.empty()) {
  114. Json::Value jsonArray = Json::arrayValue;
  115. for (auto const& value : values) {
  116. jsonArray.append(value);
  117. }
  118. object[variable.ObjectKey] = jsonArray;
  119. }
  120. }
  121. } else {
  122. cmValue def = mf->GetDefinition(variableName);
  123. if (def && (!variable.OmitEmpty || !def.IsEmpty())) {
  124. object[variable.ObjectKey] = *def;
  125. }
  126. }
  127. }
  128. }
  129. Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned int version)
  130. {
  131. Toolchains toolchains(fileAPI, version);
  132. return toolchains.Dump();
  133. }