Coverage Report

Created: 2026-06-15 07:03

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
std::string cmInstallFileSetGenerator::GetDestination() const
97
0
{
98
0
  this->CheckAbsoluteDestination(this->Destination, this->LocalGenerator);
99
0
  return this->Destination;
100
0
}
101
102
std::string cmInstallFileSetGenerator::GetDestination(
103
  std::string const& config) const
104
0
{
105
0
  return this->GetDestination(this->Target, config).UnescapedDestination;
106
0
}
107
108
cmInstallFileSetGenerator::DestinationContext
109
cmInstallFileSetGenerator::GetDestination(cmGeneratorTarget* gte,
110
                                          std::string const& config) const
111
0
{
112
0
  cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
113
0
  std::unique_ptr<cmCompiledGeneratorExpression> cge =
114
0
    ge.Parse(this->Destination);
115
116
0
  std::string const dest = cge->Evaluate(gte->LocalGenerator, config, gte);
117
0
  this->CheckAbsoluteDestination(dest, gte->LocalGenerator);
118
119
0
  return { dest, cge->GetHadContextSensitiveCondition() };
120
0
}
121
122
void cmInstallFileSetGenerator::GenerateScriptForConfig(
123
  std::ostream& os, std::string const& config, Indent indent)
124
0
{
125
126
0
  if (!this->FileSet) {
127
0
    return;
128
0
  }
129
130
0
  for (auto const& dirEntry : this->CalculateFilesPerDir(config)) {
131
0
    std::string destSub;
132
0
    if (!dirEntry.first.empty()) {
133
0
      destSub = cmStrCat('/', dirEntry.first);
134
0
    }
135
0
    this->AddInstallRule(os, cmStrCat(this->GetDestination(config), destSub),
136
0
                         cmInstallType_FILES, dirEntry.second,
137
0
                         this->GetOptional(), this->FilePermissions.c_str(),
138
0
                         nullptr, nullptr, nullptr, indent);
139
0
  }
140
0
}
141
142
std::map<std::string, std::vector<std::string>>
143
cmInstallFileSetGenerator::CalculateFilesPerDir(
144
  std::string const& config) const
145
0
{
146
0
  cm::GenEx::Context context(this->LocalGenerator, config);
147
148
0
  return this->FileSet->GetFiles(context, this->Target).first;
149
0
}