Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmInstallFileSetGenerator.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 "cmInstallFileSetGenerator.h"
4
5
#include <algorithm>
6
#include <map>
7
#include <memory>
8
#include <string>
9
#include <utility>
10
#include <vector>
11
12
#include <cm/string_view>
13
14
#include "cmDiagnosticContext.h"
15
#include "cmFileSetMetadata.h"
16
#include "cmGenExContext.h"
17
#include "cmGeneratorExpression.h"
18
#include "cmGeneratorFileSet.h"
19
#include "cmGeneratorTarget.h"
20
#include "cmGlobalGenerator.h"
21
#include "cmInstallDirs.h"
22
#include "cmInstallType.h"
23
#include "cmList.h"
24
#include "cmLocalGenerator.h"
25
#include "cmMakefile.h"
26
#include "cmMessageType.h"
27
#include "cmStringAlgorithms.h"
28
#include "cmTarget.h"
29
30
cmInstallFileSetGenerator::cmInstallFileSetGenerator(
31
  std::string targetName, std::string fileSetName, std::string destination,
32
  std::string filePermissions, std::vector<std::string> const& configurations,
33
  std::string const& component, MessageLevel message, bool excludeFromAll,
34
  bool optional, cmDiagnosticContext context)
35
0
  : cmInstallGenerator(std::move(destination), configurations, component,
36
0
                       message, excludeFromAll, false, std::move(context))
37
0
  , TargetName(std::move(targetName))
38
0
  , FileSetName(std::move(fileSetName))
39
0
  , FilePermissions(std::move(filePermissions))
40
0
  , Optional(optional)
41
0
{
42
0
  this->ActionsPerConfig = true;
43
0
}
44
45
0
cmInstallFileSetGenerator::~cmInstallFileSetGenerator() = default;
46
47
bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
48
0
{
49
0
  this->LocalGenerator = lg;
50
51
  // Lookup this target in the current directory.
52
0
  this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName);
53
0
  if (!this->Target) {
54
    // If no local target has been found, find it in the global scope.
55
0
    this->Target =
56
0
      lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
57
0
  }
58
59
0
  this->FileSet = this->Target->GetFileSet(this->FileSetName);
60
61
0
  if (!this->FileSet) {
62
    // No file set of the given name was ever provided for this target, nothing
63
    // for this generator to do
64
0
    return true;
65
0
  }
66
67
0
  auto const& target = *this->Target->Target;
68
0
  cmList interfaceFileSetEntries{ target.GetSafeProperty(
69
0
    target.GetInterfaceFileSetsPropertyName(this->FileSet->GetType())) };
70
71
0
  if (std::find(interfaceFileSetEntries.begin(), interfaceFileSetEntries.end(),
72
0
                this->FileSetName) != interfaceFileSetEntries.end()) {
73
0
    if (this->FileSet->GetType() == cm::FileSetMetadata::HEADERS) {
74
0
      if (this->Destination.empty()) {
75
0
        this->Destination =
76
0
          cm::InstallDirs::GetIncludeDirectory(lg->GetMakefile());
77
0
      }
78
0
    }
79
0
  } else {
80
    // File set of the given name was provided but it's private, so give up
81
0
    this->FileSet = nullptr;
82
0
    return true;
83
0
  }
84
85
0
  if (this->Destination.empty()) {
86
0
    lg->IssueMessage(MessageType::FATAL_ERROR,
87
0
                     cmStrCat("File set \"", this->FileSetName,
88
0
                              "\" installed by target \"", this->TargetName,
89
0
                              "\" has no destination."));
90
0
    return false;
91
0
  }
92
93
0
  return true;
94
0
}
95
96
void cmInstallFileSetGenerator::GetInstallBuildDependencies(
97
  std::string const& config, std::vector<BuildDependency>& dependencies) const
98
0
{
99
0
  if (!this->FileSet) {
100
0
    return;
101
0
  }
102
103
0
  std::vector<std::string> files;
104
0
  for (auto const& dirEntry : this->CalculateFilesPerDir(config)) {
105
0
    files.insert(files.end(), dirEntry.second.begin(), dirEntry.second.end());
106
0
  }
107
0
  AddGeneratedFileDependencies(this->LocalGenerator->GetGlobalGenerator(),
108
0
                               config, this->Target, files, dependencies);
109
0
}
110
111
std::string cmInstallFileSetGenerator::GetDestination() const
112
0
{
113
0
  this->CheckAbsoluteDestination(this->Destination, this->LocalGenerator);
114
0
  return this->Destination;
115
0
}
116
117
std::string cmInstallFileSetGenerator::GetDestination(
118
  std::string const& config) const
119
0
{
120
0
  return this->GetDestination(this->Target, config).UnescapedDestination;
121
0
}
122
123
cmInstallFileSetGenerator::DestinationContext
124
cmInstallFileSetGenerator::GetDestination(cmGeneratorTarget const* gte,
125
                                          std::string const& config) const
126
0
{
127
0
  cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
128
0
  std::unique_ptr<cmCompiledGeneratorExpression> cge =
129
0
    ge.Parse(this->Destination);
130
131
0
  std::string const dest = cge->Evaluate(gte->LocalGenerator, config, gte);
132
0
  this->CheckAbsoluteDestination(dest, gte->LocalGenerator);
133
134
0
  return { dest, cge->GetHadContextSensitiveCondition() };
135
0
}
136
137
void cmInstallFileSetGenerator::GenerateScriptForConfig(
138
  std::ostream& os, std::string const& config, Indent indent)
139
0
{
140
141
0
  if (!this->FileSet) {
142
0
    return;
143
0
  }
144
145
0
  for (auto const& dirEntry : this->CalculateFilesPerDir(config)) {
146
0
    std::string destSub;
147
0
    if (!dirEntry.first.empty()) {
148
0
      destSub = cmStrCat('/', dirEntry.first);
149
0
    }
150
0
    this->AddInstallRule(os, cmStrCat(this->GetDestination(config), destSub),
151
0
                         cmInstallType_FILES, dirEntry.second,
152
0
                         this->GetOptional(), this->FilePermissions.c_str(),
153
0
                         nullptr, nullptr, nullptr, indent);
154
0
  }
155
0
}
156
157
std::map<std::string, std::vector<std::string>>
158
cmInstallFileSetGenerator::CalculateFilesPerDir(
159
  std::string const& config) const
160
0
{
161
0
  cm::GenEx::Context context(this->LocalGenerator, config);
162
163
0
  return this->FileSet->GetFiles(context, this->Target).first;
164
0
}