Coverage Report

Created: 2026-10-28 06:38

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