Coverage Report

Created: 2026-04-29 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmGeneratorFileSet.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 "cmGeneratorFileSet.h"
4
5
#include <algorithm>
6
#include <map>
7
#include <sstream>
8
#include <unordered_map>
9
#include <unordered_set>
10
#include <utility>
11
#include <vector>
12
13
#include <cm/memory>
14
#include <cm/optional>
15
#include <cm/string_view>
16
#include <cmext/string_view>
17
18
#include "cmAlgorithms.h"
19
#include "cmEvaluatedTargetProperty.h"
20
#include "cmFileSet.h"
21
#include "cmGenExContext.h"
22
#include "cmGeneratorExpression.h"
23
#include "cmGeneratorExpressionDAGChecker.h"
24
#include "cmGeneratorTarget.h"
25
#include "cmList.h"
26
#include "cmListFileCache.h"
27
#include "cmLocalGenerator.h"
28
#include "cmMakefile.h"
29
#include "cmMessageType.h"
30
#include "cmStringAlgorithms.h"
31
#include "cmSystemTools.h"
32
#include "cmake.h"
33
34
class cmLinkItem;
35
36
namespace {
37
class FileSetPropertyEntry : public cm::TargetPropertyEntry
38
{
39
public:
40
  FileSetPropertyEntry(
41
    std::vector<std::string> dirs, bool contextSensitiveDirs,
42
    std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
43
    cmGeneratorFileSet const* fileSet, cmLinkItem const& item = NoLinkItem)
44
0
    : cm::TargetPropertyEntry(item)
45
0
    , BaseDirs(std::move(dirs))
46
0
    , ContextSensitiveDirs(contextSensitiveDirs)
47
0
    , Cge(cge)
48
0
    , FileSet(fileSet)
49
0
  {
50
0
  }
51
52
  static std::unique_ptr<cm::TargetPropertyEntry> CreateFileSetEntry(
53
    std::vector<std::string> dirs, bool contextSensitiveDirs,
54
    std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
55
    cmGeneratorFileSet const* fileSet, cmLinkItem const& item = NoLinkItem)
56
0
  {
57
0
    return cm::make_unique<FileSetPropertyEntry>(
58
0
      std::move(dirs), contextSensitiveDirs, cge, fileSet, item);
59
0
  }
60
61
  std::string const& Evaluate(
62
    cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
63
    cmGeneratorExpressionDAGChecker* dagChecker) const override
64
0
  {
65
0
    std::map<std::string, std::vector<std::string>> filesPerDir;
66
0
    this->FileSet->EvaluateFileEntry(this->BaseDirs, filesPerDir, this->Cge,
67
0
                                     context, headTarget, dagChecker);
68
69
0
    std::vector<std::string> files;
70
0
    for (auto const& it : filesPerDir) {
71
0
      files.insert(files.end(), it.second.begin(), it.second.end());
72
0
    }
73
74
0
    this->Value = cmList::to_string(files);
75
0
    return Value;
76
0
  }
77
78
  cmListFileBacktrace GetBacktrace() const override
79
0
  {
80
0
    return this->Cge->GetBacktrace();
81
0
  }
82
83
  std::string const& GetInput() const override
84
0
  {
85
0
    return this->Cge->GetInput();
86
0
  }
87
88
  bool GetHadContextSensitiveCondition() const override
89
0
  {
90
0
    return this->ContextSensitiveDirs ||
91
0
      this->Cge->GetHadContextSensitiveCondition();
92
0
  }
93
94
private:
95
  std::vector<std::string> const BaseDirs;
96
  bool const ContextSensitiveDirs;
97
  std::unique_ptr<cmCompiledGeneratorExpression> const& Cge;
98
  cmGeneratorFileSet const* FileSet;
99
  mutable std::string Value;
100
};
101
102
void CreatePropertyGeneratorExpressions(
103
  cmake& cmakeInstance, cmBTStringRange entries,
104
  std::vector<std::unique_ptr<cm::TargetPropertyEntry>>& items)
105
0
{
106
0
  for (auto const& entry : entries) {
107
0
    items.emplace_back(
108
0
      cm::TargetPropertyEntry::Create(cmakeInstance, entry, false));
109
0
  }
110
0
}
111
112
enum class OptionsParse
113
{
114
  None,
115
  Shell
116
};
117
118
std::vector<BT<std::string>> ProcessOptions(
119
  cm::EvaluatedTargetPropertyEntries const& entries,
120
  OptionsParse parse = OptionsParse::None)
121
0
{
122
0
  std::vector<BT<std::string>> options;
123
0
  std::unordered_set<std::string> uniqueOptions;
124
125
0
  for (cm::EvaluatedTargetPropertyEntry const& entry : entries.Entries) {
126
0
    for (std::string const& opt : entry.Values) {
127
0
      if (uniqueOptions.insert(opt).second) {
128
0
        if (parse == OptionsParse::Shell &&
129
0
            cmHasLiteralPrefix(opt, "SHELL:")) {
130
0
          std::vector<std::string> tmp;
131
0
          cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
132
0
          for (std::string& o : tmp) {
133
0
            options.emplace_back(std::move(o), entry.Backtrace);
134
0
          }
135
0
        } else {
136
0
          options.emplace_back(opt, entry.Backtrace);
137
0
        }
138
0
      }
139
0
    }
140
0
  }
141
0
  return options;
142
0
}
143
std::vector<BT<std::string>> ProcessIncludes(
144
  cmGeneratorTarget const* target, std::string const& fileSetName,
145
  cm::string_view property, cm::EvaluatedTargetPropertyEntries& entries)
146
0
{
147
0
  std::vector<BT<std::string>> includes;
148
0
  std::unordered_set<std::string> uniqueIncludes;
149
150
0
  for (cm::EvaluatedTargetPropertyEntry& entry : entries.Entries) {
151
0
    for (std::string& include : entry.Values) {
152
0
      if (!cmValue::IsOff(include)) {
153
0
        cmSystemTools::ConvertToUnixSlashes(include);
154
0
      }
155
156
0
      if (!cmSystemTools::FileIsFullPath(include)) {
157
0
        target->GetLocalGenerator()->IssueMessage(
158
0
          MessageType::FATAL_ERROR,
159
0
          cmStrCat("File set \"", fileSetName, "\" from the target \"",
160
0
                   target->GetName(), "\" contains relative path in its ",
161
0
                   property, ":\n  \"", include, "\""));
162
0
        return includes;
163
0
      }
164
165
0
      if (uniqueIncludes.insert(include).second) {
166
0
        includes.emplace_back(include, entry.Backtrace);
167
0
      }
168
0
    }
169
0
  }
170
0
  return includes;
171
0
}
172
}
173
174
//
175
// Class cmGeneratorFileSet
176
//
177
cmGeneratorFileSet::cmGeneratorFileSet(cmGeneratorTarget const* target,
178
                                       cmFileSet const* fileSet)
179
0
  : Target(target)
180
0
  , FileSet(fileSet)
181
0
{
182
0
  auto& cmake = *target->GetLocalGenerator()->GetCMakeInstance();
183
184
0
  CreatePropertyGeneratorExpressions(cmake, fileSet->GetIncludeDirectories(),
185
0
                                     this->IncludeDirectories);
186
0
  CreatePropertyGeneratorExpressions(cmake,
187
0
                                     fileSet->GetInterfaceIncludeDirectories(),
188
0
                                     this->InterfaceIncludeDirectories);
189
190
0
  CreatePropertyGeneratorExpressions(cmake, fileSet->GetCompileOptions(),
191
0
                                     this->CompileOptions);
192
0
  CreatePropertyGeneratorExpressions(cmake,
193
0
                                     fileSet->GetInterfaceCompileOptions(),
194
0
                                     this->InterfaceCompileOptions);
195
196
0
  CreatePropertyGeneratorExpressions(cmake, fileSet->GetCompileDefinitions(),
197
0
                                     this->CompileDefinitions);
198
0
  CreatePropertyGeneratorExpressions(cmake,
199
0
                                     fileSet->GetInterfaceCompileDefinitions(),
200
0
                                     this->InterfaceCompileDefinitions);
201
0
}
202
203
std::string const& cmGeneratorFileSet::GetName() const
204
0
{
205
0
  return this->FileSet->GetName();
206
0
}
207
std::string const& cmGeneratorFileSet::GetType() const
208
0
{
209
0
  return this->FileSet->GetType();
210
0
}
211
cm::FileSetMetadata::Visibility cmGeneratorFileSet::GetVisibility() const
212
0
{
213
0
  return this->FileSet->GetVisibility();
214
0
}
215
216
bool cmGeneratorFileSet::IsForSelf() const
217
0
{
218
0
  return this->FileSet->IsForSelf();
219
0
}
220
bool cmGeneratorFileSet::IsForInterface() const
221
0
{
222
0
  return this->FileSet->IsForInterface();
223
0
}
224
bool cmGeneratorFileSet::CanBeIncluded() const
225
0
{
226
0
  return this->FileSet->CanBeIncluded();
227
0
}
228
229
cmValue cmGeneratorFileSet::GetProperty(std::string const& prop) const
230
0
{
231
0
  return this->FileSet->GetProperty(prop);
232
0
}
233
234
std::vector<BT<std::string>> cmGeneratorFileSet::GetIncludeDirectories(
235
  std::string const& config, std::string const& lang) const
236
0
{
237
0
  ConfigAndLanguage cacheKey(config, lang);
238
0
  {
239
0
    auto it = this->IncludeDirectoriesCache.find(cacheKey);
240
0
    if (it != this->IncludeDirectoriesCache.end()) {
241
0
      return it->second;
242
0
    }
243
0
  }
244
245
0
  cm::GenEx::Context context(this->Target->GetLocalGenerator(), config, lang);
246
0
  cmGeneratorExpressionDAGChecker dagChecker{
247
0
    this->Target, "INCLUDE_DIRECTORIES", nullptr, nullptr, context,
248
0
  };
249
250
0
  cm::EvaluatedTargetPropertyEntries entries =
251
0
    cm::EvaluateTargetPropertyEntries(this->Target, context, &dagChecker,
252
0
                                      this->IncludeDirectories);
253
0
  auto includes = ProcessIncludes(this->Target, this->GetName(),
254
0
                                  "INCLUDE_DIRECTORIES"_s, entries);
255
0
  this->IncludeDirectoriesCache.emplace(cacheKey, includes);
256
257
0
  return includes;
258
0
}
259
std::vector<BT<std::string>>
260
cmGeneratorFileSet::GetInterfaceIncludeDirectories(
261
  std::string const& config, std::string const& lang) const
262
0
{
263
0
  ConfigAndLanguage cacheKey(config, lang);
264
0
  {
265
0
    auto it = this->InterfaceIncludeDirectoriesCache.find(cacheKey);
266
0
    if (it != this->InterfaceIncludeDirectoriesCache.end()) {
267
0
      return it->second;
268
0
    }
269
0
  }
270
271
0
  cm::GenEx::Context context(this->Target->GetLocalGenerator(), config, lang);
272
0
  cmGeneratorExpressionDAGChecker dagChecker{
273
0
    this->Target, "INCLUDE_DIRECTORIES", nullptr, nullptr, context,
274
0
  };
275
276
0
  cm::EvaluatedTargetPropertyEntries entries =
277
0
    cm::EvaluateTargetPropertyEntries(this->Target, context, &dagChecker,
278
0
                                      this->InterfaceIncludeDirectories);
279
0
  auto includes = ProcessIncludes(this->Target, this->GetName(),
280
0
                                  "INTERFACE_INCLUDE_DIRECTORIES"_s, entries);
281
0
  this->InterfaceIncludeDirectoriesCache.emplace(cacheKey, includes);
282
283
0
  return includes;
284
0
}
285
286
std::vector<BT<std::string>> cmGeneratorFileSet::GetCompileOptions(
287
  std::string const& config, std::string const& language) const
288
0
{
289
0
  ConfigAndLanguage cacheKey(config, language);
290
0
  {
291
0
    auto it = this->CompileOptionsCache.find(cacheKey);
292
0
    if (it != this->CompileOptionsCache.end()) {
293
0
      return it->second;
294
0
    }
295
0
  }
296
297
0
  cm::GenEx::Context context(this->Target->GetLocalGenerator(), config,
298
0
                             language);
299
0
  cmGeneratorExpressionDAGChecker dagChecker{
300
0
    this->Target, "COMPILE_OPTIONS", nullptr, nullptr, context,
301
0
  };
302
303
0
  cm::EvaluatedTargetPropertyEntries entries =
304
0
    cm::EvaluateTargetPropertyEntries(this->Target, context, &dagChecker,
305
0
                                      this->CompileOptions);
306
0
  auto options = ProcessOptions(entries, OptionsParse::Shell);
307
0
  this->CompileOptionsCache.emplace(cacheKey, options);
308
309
0
  return options;
310
0
}
311
std::vector<BT<std::string>> cmGeneratorFileSet::GetInterfaceCompileOptions(
312
  std::string const& config, std::string const& language) const
313
0
{
314
0
  ConfigAndLanguage cacheKey(config, language);
315
0
  {
316
0
    auto it = this->InterfaceCompileOptionsCache.find(cacheKey);
317
0
    if (it != this->InterfaceCompileOptionsCache.end()) {
318
0
      return it->second;
319
0
    }
320
0
  }
321
322
0
  cm::GenEx::Context context(this->Target->GetLocalGenerator(), config,
323
0
                             language);
324
0
  cmGeneratorExpressionDAGChecker dagChecker{
325
0
    this->Target, "COMPILE_OPTIONS", nullptr, nullptr, context,
326
0
  };
327
328
0
  cm::EvaluatedTargetPropertyEntries entries =
329
0
    cm::EvaluateTargetPropertyEntries(this->Target, context, &dagChecker,
330
0
                                      this->InterfaceCompileOptions);
331
0
  auto options = ProcessOptions(entries, OptionsParse::Shell);
332
0
  this->InterfaceCompileOptionsCache.emplace(cacheKey, options);
333
334
0
  return options;
335
0
}
336
337
std::vector<BT<std::string>> cmGeneratorFileSet::GetCompileDefinitions(
338
  std::string const& config, std::string const& language) const
339
0
{
340
0
  ConfigAndLanguage cacheKey(config, language);
341
0
  {
342
0
    auto it = this->CompileDefinitionsCache.find(cacheKey);
343
0
    if (it != this->CompileDefinitionsCache.end()) {
344
0
      return it->second;
345
0
    }
346
0
  }
347
348
0
  cm::GenEx::Context context(this->Target->GetLocalGenerator(), config,
349
0
                             language);
350
0
  cmGeneratorExpressionDAGChecker dagChecker{
351
0
    this->Target, "COMPILE_DEFINITIONS", nullptr, nullptr, context,
352
0
  };
353
354
0
  cm::EvaluatedTargetPropertyEntries entries =
355
0
    cm::EvaluateTargetPropertyEntries(this->Target, context, &dagChecker,
356
0
                                      this->CompileDefinitions);
357
0
  auto defines = ProcessOptions(entries);
358
0
  this->CompileDefinitionsCache.emplace(cacheKey, defines);
359
360
0
  return defines;
361
0
}
362
std::vector<BT<std::string>>
363
cmGeneratorFileSet::GetInterfaceCompileDefinitions(
364
  std::string const& config, std::string const& language) const
365
0
{
366
0
  ConfigAndLanguage cacheKey(config, language);
367
0
  {
368
0
    auto it = this->InterfaceCompileDefinitionsCache.find(cacheKey);
369
0
    if (it != this->InterfaceCompileDefinitionsCache.end()) {
370
0
      return it->second;
371
0
    }
372
0
  }
373
374
0
  cm::GenEx::Context context(this->Target->GetLocalGenerator(), config,
375
0
                             language);
376
0
  cmGeneratorExpressionDAGChecker dagChecker{
377
0
    this->Target, "COMPILE_DEFINITIONS", nullptr, nullptr, context,
378
0
  };
379
380
0
  cm::EvaluatedTargetPropertyEntries entries =
381
0
    cm::EvaluateTargetPropertyEntries(this->Target, context, &dagChecker,
382
0
                                      this->InterfaceCompileDefinitions);
383
0
  auto defines = ProcessOptions(entries);
384
0
  this->InterfaceCompileDefinitionsCache.emplace(cacheKey, defines);
385
386
0
  return defines;
387
0
}
388
389
std::vector<BT<std::string>> const& cmGeneratorFileSet::GetDirectoryEntries()
390
  const
391
0
{
392
0
  return this->FileSet->GetDirectoryEntries();
393
0
}
394
395
std::vector<BT<std::string>> const& cmGeneratorFileSet::GetFileEntries() const
396
0
{
397
0
  return this->FileSet->GetFileEntries();
398
0
}
399
400
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const&
401
cmGeneratorFileSet::CompileFileEntries() const
402
0
{
403
0
  std::unordered_set<std::string> uniqueSrcs;
404
405
0
  if (this->CompiledFileEntries.empty() &&
406
0
      !this->FileSet->GetFileEntries().empty()) {
407
0
    for (auto const& entry : this->FileSet->GetFileEntries()) {
408
0
      for (auto const& ex : cmList{ entry.Value }) {
409
0
        if (uniqueSrcs.insert(ex).second) {
410
0
          cmGeneratorExpression ge(
411
0
            *this->FileSet->GetMakefile()->GetCMakeInstance(),
412
0
            entry.Backtrace);
413
0
          auto cge = ge.Parse(ex);
414
0
          this->CompiledFileEntries.push_back(std::move(cge));
415
0
        }
416
0
      }
417
0
    }
418
0
  }
419
420
0
  return this->CompiledFileEntries;
421
0
}
422
423
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const&
424
cmGeneratorFileSet::CompileDirectoryEntries() const
425
0
{
426
0
  if (this->CompiledDirectoryEntries.empty() &&
427
0
      !this->FileSet->GetDirectoryEntries().empty()) {
428
0
    for (auto const& entry : this->FileSet->GetDirectoryEntries()) {
429
0
      for (auto const& ex : cmList{ entry.Value }) {
430
0
        cmGeneratorExpression ge(
431
0
          *this->FileSet->GetMakefile()->GetCMakeInstance(), entry.Backtrace);
432
0
        auto cge = ge.Parse(ex);
433
0
        this->CompiledDirectoryEntries.push_back(std::move(cge));
434
0
      }
435
0
    }
436
0
  }
437
438
0
  return this->CompiledDirectoryEntries;
439
0
}
440
441
std::vector<std::string> cmGeneratorFileSet::EvaluateDirectoryEntries(
442
  std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
443
  cm::GenEx::Context const& context, cmGeneratorTarget const* target,
444
  cmGeneratorExpressionDAGChecker* dagChecker) const
445
0
{
446
0
  struct DirCacheEntry
447
0
  {
448
0
    std::string collapsedDir;
449
0
    cm::optional<cmSystemTools::FileId> fileId;
450
0
  };
451
452
0
  std::unordered_map<std::string, DirCacheEntry> dirCache;
453
0
  std::vector<std::string> result;
454
0
  for (auto const& cge : cges) {
455
0
    auto entry = cge->Evaluate(context, dagChecker, target);
456
0
    cmList dirs{ entry };
457
0
    for (std::string dir : dirs) {
458
0
      if (!cmSystemTools::FileIsFullPath(dir)) {
459
0
        dir = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', dir);
460
0
      }
461
462
0
      auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry());
463
0
      auto& dirCacheEntry = dirCacheResult.first->second;
464
0
      auto const isNewCacheEntry = dirCacheResult.second;
465
466
0
      if (isNewCacheEntry) {
467
0
        cmSystemTools::FileId fileId;
468
0
        auto isFileIdValid = cmSystemTools::GetFileId(dir, fileId);
469
0
        dirCacheEntry.collapsedDir = cmSystemTools::CollapseFullPath(dir);
470
0
        dirCacheEntry.fileId =
471
0
          isFileIdValid ? cm::optional<decltype(fileId)>(fileId) : cm::nullopt;
472
0
      }
473
474
0
      for (auto const& priorDir : result) {
475
0
        auto priorDirCacheEntry = dirCache.at(priorDir);
476
0
        bool sameFile = dirCacheEntry.fileId.has_value() &&
477
0
          priorDirCacheEntry.fileId.has_value() &&
478
0
          (*dirCacheEntry.fileId == *priorDirCacheEntry.fileId);
479
0
        if (!sameFile &&
480
0
            (cmSystemTools::IsSubDirectory(dirCacheEntry.collapsedDir,
481
0
                                           priorDirCacheEntry.collapsedDir) ||
482
0
             cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir,
483
0
                                           dirCacheEntry.collapsedDir))) {
484
0
          context.LG->GetCMakeInstance()->IssueMessage(
485
0
            MessageType::FATAL_ERROR,
486
0
            cmStrCat(
487
0
              "Base directories in file set cannot be subdirectories of each "
488
0
              "other:\n  ",
489
0
              priorDir, "\n  ", dir),
490
0
            cge->GetBacktrace());
491
0
          return {};
492
0
        }
493
0
      }
494
0
      result.push_back(dir);
495
0
    }
496
0
  }
497
0
  return result;
498
0
}
499
500
void cmGeneratorFileSet::EvaluateFileEntry(
501
  std::vector<std::string> const& dirs,
502
  std::map<std::string, std::vector<std::string>>& filesPerDir,
503
  std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
504
  cm::GenEx::Context const& context, cmGeneratorTarget const* target,
505
  cmGeneratorExpressionDAGChecker* dagChecker) const
506
0
{
507
0
  auto files = cge->Evaluate(context, dagChecker, target);
508
0
  for (std::string file : cmList{ files }) {
509
0
    if (!cmSystemTools::FileIsFullPath(file)) {
510
0
      file = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', file);
511
0
    }
512
0
    auto collapsedFile = cmSystemTools::CollapseFullPath(file);
513
0
    bool found = false;
514
0
    std::string relDir;
515
0
    for (auto const& dir : dirs) {
516
0
      auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
517
0
      if (cmSystemTools::IsSubDirectory(collapsedFile, collapsedDir)) {
518
0
        found = true;
519
0
        relDir = cmSystemTools::GetParentDirectory(
520
0
          cmSystemTools::RelativePath(collapsedDir, collapsedFile));
521
0
        break;
522
0
      }
523
0
    }
524
0
    if (!found) {
525
0
      std::ostringstream e;
526
0
      e << "File:\n  " << file
527
0
        << "\nmust be in one of the file set's base directories:";
528
0
      for (auto const& dir : dirs) {
529
0
        e << "\n  " << dir;
530
0
      }
531
0
      context.LG->GetCMakeInstance()->IssueMessage(
532
0
        MessageType::FATAL_ERROR, e.str(), cge->GetBacktrace());
533
0
      return;
534
0
    }
535
536
0
    filesPerDir[relDir].push_back(file);
537
0
  }
538
0
}
539
540
namespace {
541
bool EntryIsContextSensitive(
542
  std::unique_ptr<cmCompiledGeneratorExpression> const& cge)
543
0
{
544
0
  return cge->GetHadContextSensitiveCondition();
545
0
}
546
}
547
548
std::vector<std::unique_ptr<cm::TargetPropertyEntry>>
549
cmGeneratorFileSet::GetSources(
550
  cm::GenEx::Context const& context, cmGeneratorTarget const* target,
551
  cmGeneratorExpressionDAGChecker* dagChecker) const
552
0
{
553
0
  std::vector<std::unique_ptr<TargetPropertyEntry>> entries;
554
555
0
  auto directories = this->GetDirectories(context, target, dagChecker);
556
0
  bool contextSensitive = directories.second;
557
558
0
  for (auto const& entry : this->CompileFileEntries()) {
559
0
    auto propEntry = FileSetPropertyEntry::CreateFileSetEntry(
560
0
      directories.first, contextSensitive, entry, this);
561
0
    entries.push_back(std::move(propEntry));
562
0
  }
563
564
0
  return entries;
565
0
}
566
567
std::pair<std::vector<std::string>, bool> cmGeneratorFileSet::GetDirectories(
568
  cm::GenEx::Context const& context, cmGeneratorTarget const* target,
569
  cmGeneratorExpressionDAGChecker* dagChecker) const
570
0
{
571
0
  auto const& directoryEntries = this->CompileDirectoryEntries();
572
0
  auto directories = this->EvaluateDirectoryEntries(directoryEntries, context,
573
0
                                                    target, dagChecker);
574
0
  bool contextSensitive = std::any_of(
575
0
    directoryEntries.begin(), directoryEntries.end(), EntryIsContextSensitive);
576
577
0
  return std::make_pair(std::move(directories), contextSensitive);
578
0
}
579
580
std::pair<std::map<std::string, std::vector<std::string>>, bool>
581
cmGeneratorFileSet::GetFiles(cm::GenEx::Context const& context,
582
                             cmGeneratorTarget const* target,
583
                             cmGeneratorExpressionDAGChecker* dagChecker) const
584
0
{
585
0
  auto directories = this->GetDirectories(context, target, dagChecker);
586
587
0
  auto const& fileEntries = this->CompileFileEntries();
588
0
  std::map<std::string, std::vector<std::string>> files;
589
0
  for (auto const& entry : fileEntries) {
590
0
    this->EvaluateFileEntry(directories.first, files, entry, context, target,
591
0
                            dagChecker);
592
0
  }
593
0
  bool contextSensitive = directories.second ||
594
0
    std::any_of(fileEntries.begin(), fileEntries.end(),
595
0
                EntryIsContextSensitive);
596
597
0
  return std::make_pair(std::move(files), contextSensitive);
598
0
}