Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmFileAPIToolchains.cxx
Line
Count
Source
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
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 "cmList.h"
14
#include "cmMakefile.h"
15
#include "cmState.h"
16
#include "cmStringAlgorithms.h"
17
#include "cmValue.h"
18
#include "cmake.h"
19
20
namespace {
21
22
struct ToolchainVariable
23
{
24
  std::string ObjectKey;
25
  std::string VariableSuffix;
26
  bool IsList;
27
  bool OmitEmpty;
28
};
29
30
class Toolchains
31
{
32
  cmFileAPI& FileAPI;
33
  unsigned int Version;
34
35
  Json::Value DumpToolchains();
36
  Json::Value DumpToolchain(std::string const& lang);
37
  Json::Value DumpToolchainVariables(
38
    cmMakefile const* mf, std::string const& lang,
39
    std::vector<ToolchainVariable> const& variables);
40
  void DumpToolchainVariable(cmMakefile const* mf, Json::Value& object,
41
                             std::string const& lang,
42
                             ToolchainVariable const& variable);
43
44
public:
45
  Toolchains(cmFileAPI& fileAPI, unsigned int version);
46
  Json::Value Dump();
47
};
48
49
Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned int version)
50
0
  : FileAPI(fileAPI)
51
0
  , Version(version)
52
0
{
53
0
  static_cast<void>(this->Version);
54
0
}
55
56
Json::Value Toolchains::Dump()
57
0
{
58
0
  Json::Value toolchains = Json::objectValue;
59
0
  toolchains["toolchains"] = this->DumpToolchains();
60
0
  return toolchains;
61
0
}
62
63
Json::Value Toolchains::DumpToolchains()
64
0
{
65
0
  Json::Value toolchains = Json::arrayValue;
66
67
0
  for (std::string const& lang :
68
0
       this->FileAPI.GetCMakeInstance()->GetState()->GetEnabledLanguages()) {
69
0
    toolchains.append(this->DumpToolchain(lang));
70
0
  }
71
72
0
  return toolchains;
73
0
}
74
75
Json::Value Toolchains::DumpToolchain(std::string const& lang)
76
0
{
77
0
  static std::vector<ToolchainVariable> const CompilerVariables{
78
0
    { "path", "COMPILER", false, false },
79
0
    { "commandFragment", "COMPILER_ARG1", false, true },
80
0
    { "id", "COMPILER_ID", false, false },
81
0
    { "version", "COMPILER_VERSION", false, false },
82
0
    { "target", "COMPILER_TARGET", false, false },
83
0
  };
84
85
0
  static std::vector<ToolchainVariable> const CompilerImplicitVariables{
86
0
    { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true, false },
87
0
    { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true, false },
88
0
    { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true,
89
0
      false },
90
0
    { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true, false },
91
0
  };
92
93
0
  static ToolchainVariable const SourceFileExtensionsVariable{
94
0
    "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true, false
95
0
  };
96
97
0
  auto const& mf =
98
0
    this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0];
99
0
  Json::Value toolchain = Json::objectValue;
100
0
  toolchain["language"] = lang;
101
0
  toolchain["compiler"] =
102
0
    this->DumpToolchainVariables(mf.get(), lang, CompilerVariables);
103
0
  toolchain["compiler"]["implicit"] =
104
0
    this->DumpToolchainVariables(mf.get(), lang, CompilerImplicitVariables);
105
0
  this->DumpToolchainVariable(mf.get(), toolchain, lang,
106
0
                              SourceFileExtensionsVariable);
107
0
  return toolchain;
108
0
}
109
110
Json::Value Toolchains::DumpToolchainVariables(
111
  cmMakefile const* mf, std::string const& lang,
112
  std::vector<ToolchainVariable> const& variables)
113
0
{
114
0
  Json::Value object = Json::objectValue;
115
0
  for (auto const& variable : variables) {
116
0
    this->DumpToolchainVariable(mf, object, lang, variable);
117
0
  }
118
0
  return object;
119
0
}
120
121
void Toolchains::DumpToolchainVariable(cmMakefile const* mf,
122
                                       Json::Value& object,
123
                                       std::string const& lang,
124
                                       ToolchainVariable const& variable)
125
0
{
126
0
  std::string const variableName =
127
0
    cmStrCat("CMAKE_", lang, '_', variable.VariableSuffix);
128
129
0
  if (variable.IsList) {
130
0
    cmValue data = mf->GetDefinition(variableName);
131
0
    if (data) {
132
0
      cmList values(data);
133
0
      if (!variable.OmitEmpty || !values.empty()) {
134
0
        Json::Value jsonArray = Json::arrayValue;
135
0
        for (auto const& value : values) {
136
0
          jsonArray.append(value);
137
0
        }
138
0
        object[variable.ObjectKey] = jsonArray;
139
0
      }
140
0
    }
141
0
  } else {
142
0
    cmValue def = mf->GetDefinition(variableName);
143
0
    if (def && (!variable.OmitEmpty || !def.IsEmpty())) {
144
0
      object[variable.ObjectKey] = *def;
145
0
    }
146
0
  }
147
0
}
148
}
149
150
Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned int version)
151
0
{
152
0
  Toolchains toolchains(fileAPI, version);
153
0
  return toolchains.Dump();
154
0
}