Coverage Report

Created: 2026-07-14 07:09

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
    if (lang == "NONE") {
70
0
      continue;
71
0
    }
72
0
    toolchains.append(this->DumpToolchain(lang));
73
0
  }
74
75
0
  return toolchains;
76
0
}
77
78
Json::Value Toolchains::DumpToolchain(std::string const& lang)
79
0
{
80
0
  static std::vector<ToolchainVariable> const CompilerVariables{
81
0
    { "path", "COMPILER", false, false },
82
0
    { "commandFragment", "COMPILER_ARG1", false, true },
83
0
    { "id", "COMPILER_ID", false, false },
84
0
    { "version", "COMPILER_VERSION", false, false },
85
0
    { "target", "COMPILER_TARGET", false, false },
86
0
  };
87
88
0
  static std::vector<ToolchainVariable> const CompilerImplicitVariables{
89
0
    { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true, false },
90
0
    { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true, false },
91
0
    { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true,
92
0
      false },
93
0
    { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true, false },
94
0
  };
95
96
0
  static ToolchainVariable const SourceFileExtensionsVariable{
97
0
    "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true, false
98
0
  };
99
100
0
  auto const& mf =
101
0
    this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0];
102
0
  Json::Value toolchain = Json::objectValue;
103
0
  toolchain["language"] = lang;
104
0
  toolchain["compiler"] =
105
0
    this->DumpToolchainVariables(mf.get(), lang, CompilerVariables);
106
0
  toolchain["compiler"]["implicit"] =
107
0
    this->DumpToolchainVariables(mf.get(), lang, CompilerImplicitVariables);
108
0
  this->DumpToolchainVariable(mf.get(), toolchain, lang,
109
0
                              SourceFileExtensionsVariable);
110
0
  return toolchain;
111
0
}
112
113
Json::Value Toolchains::DumpToolchainVariables(
114
  cmMakefile const* mf, std::string const& lang,
115
  std::vector<ToolchainVariable> const& variables)
116
0
{
117
0
  Json::Value object = Json::objectValue;
118
0
  for (auto const& variable : variables) {
119
0
    this->DumpToolchainVariable(mf, object, lang, variable);
120
0
  }
121
0
  return object;
122
0
}
123
124
void Toolchains::DumpToolchainVariable(cmMakefile const* mf,
125
                                       Json::Value& object,
126
                                       std::string const& lang,
127
                                       ToolchainVariable const& variable)
128
0
{
129
0
  std::string const variableName =
130
0
    cmStrCat("CMAKE_", lang, '_', variable.VariableSuffix);
131
132
0
  if (variable.IsList) {
133
0
    cmValue data = mf->GetDefinition(variableName);
134
0
    if (data) {
135
0
      cmList values(data);
136
0
      if (!variable.OmitEmpty || !values.empty()) {
137
0
        Json::Value jsonArray = Json::arrayValue;
138
0
        for (auto const& value : values) {
139
0
          jsonArray.append(value);
140
0
        }
141
0
        object[variable.ObjectKey] = jsonArray;
142
0
      }
143
0
    }
144
0
  } else {
145
0
    cmValue def = mf->GetDefinition(variableName);
146
0
    if (def && (!variable.OmitEmpty || !def.IsEmpty())) {
147
0
      object[variable.ObjectKey] = *def;
148
0
    }
149
0
  }
150
0
}
151
}
152
153
Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned int version)
154
0
{
155
0
  Toolchains toolchains(fileAPI, version);
156
0
  return toolchains.Dump();
157
0
}