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