Coverage Report

Created: 2026-07-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmExportBuildPackageInfoGenerator.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 "cmExportBuildPackageInfoGenerator.h"
4
5
#include <cassert>
6
#include <functional>
7
#include <map>
8
#include <utility>
9
#include <vector>
10
11
#include <cmext/string_view>
12
13
#include <cm3p/json/value.h>
14
15
#include "cmAlgorithms.h"
16
#include "cmDiagnosticContext.h"
17
#include "cmDiagnostics.h"
18
#include "cmGenExContext.h"
19
#include "cmGeneratorExpression.h"
20
#include "cmGeneratorFileSet.h"
21
#include "cmGeneratorTarget.h"
22
#include "cmList.h"
23
#include "cmPackageInfoArguments.h"
24
#include "cmStringAlgorithms.h"
25
#include "cmTargetTypes.h"
26
27
cmExportBuildPackageInfoGenerator::cmExportBuildPackageInfoGenerator(
28
  cmPackageInfoArguments arguments, cmDiagnosticContext context)
29
0
  : cmExportBuildFileGenerator(std::move(context))
30
0
  , cmExportPackageInfoGenerator(std::move(arguments))
31
0
{
32
0
  this->SetNamespace(cmStrCat(this->GetPackageName(), "::"_s));
33
0
}
Unexecuted instantiation: cmExportBuildPackageInfoGenerator::cmExportBuildPackageInfoGenerator(cmPackageInfoArguments, cmDiagnosticContext)
Unexecuted instantiation: cmExportBuildPackageInfoGenerator::cmExportBuildPackageInfoGenerator(cmPackageInfoArguments, cmDiagnosticContext)
34
35
bool cmExportBuildPackageInfoGenerator::GenerateMainFile(std::ostream& os)
36
0
{
37
0
  if (!this->CollectExports([&](cmGeneratorTarget const*) {})) {
38
0
    return false;
39
0
  }
40
41
0
  if (!this->CheckPackage()) {
42
0
    return false;
43
0
  }
44
45
0
  Json::Value root = this->GeneratePackageInfo();
46
0
  root["cps_path"] = "@prefix@";
47
48
0
  Json::Value& components = root["components"];
49
50
  // Create all the imported targets.
51
0
  for (auto const& exp : this->Exports) {
52
0
    cmGeneratorTarget* const target = exp.Target;
53
0
    cm::TargetType targetType = this->GetExportTargetType(target);
54
55
0
    Json::Value* const component =
56
0
      this->GenerateImportTarget(components, target, targetType);
57
0
    if (!component) {
58
0
      return false;
59
0
    }
60
61
0
    ImportPropertyMap properties;
62
0
    if (!this->PopulateInterfaceProperties(target, properties)) {
63
0
      return false;
64
0
    }
65
0
    this->PopulateInterfaceLinkLibrariesProperty(
66
0
      target, cmGeneratorExpression::InstallInterface, properties);
67
68
0
    if (targetType != cm::TargetType::INTERFACE_LIBRARY) {
69
0
      auto configurations = Json::Value{ Json::objectValue };
70
71
      // Add per-configuration properties.
72
0
      for (std::string const& c : this->Configurations) {
73
0
        this->GenerateInterfacePropertiesConfig(configurations, target, c);
74
0
      }
75
76
0
      if (!configurations.empty()) {
77
0
        (*component)["configurations"] = configurations;
78
0
      }
79
0
    }
80
81
    // De-duplicate include directories prior to generation.
82
0
    auto it = properties.find("INTERFACE_INCLUDE_DIRECTORIES");
83
0
    if (it != properties.end()) {
84
0
      auto list = cmList{ it->second };
85
0
      list = cmList{ list.begin(), cmRemoveDuplicates(list) };
86
0
      properties["INTERFACE_INCLUDE_DIRECTORIES"] = list.to_string();
87
0
    }
88
89
    // Set configuration-agnostic properties for component.
90
0
    this->GenerateInterfaceProperties(*component, target, properties);
91
0
    this->GenerateTargetFileSets(*component, target);
92
0
  }
93
94
0
  this->GeneratePackageRequires(root);
95
96
  // Write the primary packing information file.
97
0
  this->WritePackageInfo(root, os);
98
99
0
  bool result = true;
100
101
0
  return result;
102
0
}
103
104
void cmExportBuildPackageInfoGenerator::GenerateInterfacePropertiesConfig(
105
  Json::Value& configurations, cmGeneratorTarget* target,
106
  std::string const& config)
107
0
{
108
0
  std::string const& suffix = PropertyConfigSuffix(config);
109
110
0
  ImportPropertyMap properties;
111
112
0
  assert(this->GetExportTargetType(target) !=
113
0
         cm::TargetType::INTERFACE_LIBRARY);
114
0
  this->SetImportLocationProperty(config, suffix, target, properties);
115
0
  if (properties.empty()) {
116
0
    return;
117
0
  }
118
119
0
  this->SetImportDetailProperties(config, suffix, target, properties);
120
121
  // TODO: PUBLIC_HEADER_LOCATION
122
123
0
  Json::Value component =
124
0
    this->GenerateInterfaceConfigProperties(suffix, properties);
125
126
0
  this->GenerateCxxModules(component, target, this->FileDir, config);
127
128
0
  if (!component.empty()) {
129
0
    configurations[config.empty() ? std::string{ "noconfig" } : config] =
130
0
      std::move(component);
131
0
  }
132
0
}
133
134
void cmExportBuildPackageInfoGenerator::GenerateTargetFileSets(
135
  Json::Value& fileSets, cmGeneratorTarget const* target,
136
  cmGeneratorFileSet const* fileSet, cmTargetExport const* /*targetExport*/,
137
  std::string const& type) const
138
0
{
139
0
  cm::GenEx::Context context{ target->LocalGenerator, {} };
140
141
0
  std::map<std::string, std::vector<std::string>> files;
142
0
  auto eval = [&files](std::string&& baseDir, std::string&& relPath,
143
0
                       std::string&& /*file*/) {
144
0
    files[std::move(baseDir)].emplace_back(std::move(relPath));
145
0
  };
146
147
0
  if (fileSet->EvaluateFiles(context, target, eval)) {
148
0
    this->IssueDiagnostic(
149
0
      cmDiagnostics::CMD_AUTHOR,
150
0
      cmStrCat("The \""_s, target->GetName(),
151
0
               "\" target's interface file set \""_s, fileSet->GetName(),
152
0
               "\" of type \""_s, fileSet->GetType(),
153
0
               "\" contains context-sensitive information, which is not "
154
0
               "supported.  The file set will not be exported."_s));
155
0
    return;
156
0
  }
157
158
0
  for (auto const& i : files) {
159
0
    this->GenerateTargetFileSet(fileSets, fileSet, type, i.first, i.second);
160
0
  }
161
0
}
162
163
std::string cmExportBuildPackageInfoGenerator::GetCxxModulesDirectory() const
164
0
{
165
0
  return this->CxxModulesDirectory;
166
0
}