Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmState.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 "cmState.h"
4
5
#include <algorithm>
6
#include <array>
7
#include <cassert>
8
#include <cstdlib>
9
#include <utility>
10
11
#include <cm/memory>
12
13
#include "cmsys/RegularExpression.hxx"
14
15
#include "cmCacheManager.h"
16
#include "cmDefinitions.h"
17
#include "cmExecutionStatus.h"
18
#include "cmGlobCacheEntry.h" // IWYU pragma: keep
19
#include "cmGlobVerificationManager.h"
20
#include "cmList.h"
21
#include "cmListFileCache.h"
22
#include "cmMakefile.h"
23
#include "cmMessageType.h"
24
#include "cmStatePrivate.h"
25
#include "cmStateSnapshot.h"
26
#include "cmStringAlgorithms.h"
27
#include "cmSystemTools.h"
28
#include "cmake.h"
29
30
namespace cmStateDetail {
31
std::string const PropertySentinel = std::string{};
32
} // namespace cmStateDetail
33
34
cmState::cmState(Role role, TryCompile isTryCompile)
35
35
  : StateRole(role)
36
35
  , IsTryCompile(isTryCompile)
37
35
{
38
35
  this->CacheManager = cm::make_unique<cmCacheManager>();
39
35
  this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>();
40
35
}
41
42
35
cmState::~cmState() = default;
43
44
std::string const& cmState::GetTargetTypeName(
45
  cmStateEnums::TargetType targetType)
46
0
{
47
0
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
48
0
  MAKE_STATIC_PROP(STATIC_LIBRARY);
49
0
  MAKE_STATIC_PROP(MODULE_LIBRARY);
50
0
  MAKE_STATIC_PROP(SHARED_LIBRARY);
51
0
  MAKE_STATIC_PROP(OBJECT_LIBRARY);
52
0
  MAKE_STATIC_PROP(EXECUTABLE);
53
0
  MAKE_STATIC_PROP(UTILITY);
54
0
  MAKE_STATIC_PROP(GLOBAL_TARGET);
55
0
  MAKE_STATIC_PROP(INTERFACE_LIBRARY);
56
0
  MAKE_STATIC_PROP(UNKNOWN_LIBRARY);
57
0
  static std::string const propEmpty;
58
0
#undef MAKE_STATIC_PROP
59
60
0
  switch (targetType) {
61
0
    case cmStateEnums::STATIC_LIBRARY:
62
0
      return propSTATIC_LIBRARY;
63
0
    case cmStateEnums::MODULE_LIBRARY:
64
0
      return propMODULE_LIBRARY;
65
0
    case cmStateEnums::SHARED_LIBRARY:
66
0
      return propSHARED_LIBRARY;
67
0
    case cmStateEnums::OBJECT_LIBRARY:
68
0
      return propOBJECT_LIBRARY;
69
0
    case cmStateEnums::EXECUTABLE:
70
0
      return propEXECUTABLE;
71
0
    case cmStateEnums::UTILITY:
72
0
      return propUTILITY;
73
0
    case cmStateEnums::GLOBAL_TARGET:
74
0
      return propGLOBAL_TARGET;
75
0
    case cmStateEnums::INTERFACE_LIBRARY:
76
0
      return propINTERFACE_LIBRARY;
77
0
    case cmStateEnums::UNKNOWN_LIBRARY:
78
0
      return propUNKNOWN_LIBRARY;
79
0
  }
80
0
  assert(false && "Unexpected target type");
81
0
  return propEmpty;
82
0
}
83
84
static std::array<std::string, 7> const cmCacheEntryTypes = {
85
  { "BOOL", "PATH", "FILEPATH", "STRING", "INTERNAL", "STATIC",
86
    "UNINITIALIZED" }
87
};
88
89
std::string const& cmState::CacheEntryTypeToString(
90
  cmStateEnums::CacheEntryType type)
91
0
{
92
0
  if (type < cmStateEnums::BOOL || type > cmStateEnums::UNINITIALIZED) {
93
0
    type = cmStateEnums::UNINITIALIZED;
94
0
  }
95
0
  return cmCacheEntryTypes[type];
96
0
}
97
98
cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(
99
  std::string const& s)
100
0
{
101
0
  cmStateEnums::CacheEntryType type = cmStateEnums::STRING;
102
0
  StringToCacheEntryType(s, type);
103
0
  return type;
104
0
}
105
106
bool cmState::StringToCacheEntryType(std::string const& s,
107
                                     cmStateEnums::CacheEntryType& type)
108
0
{
109
  // NOLINTNEXTLINE(readability-qualified-auto)
110
0
  auto const entry =
111
0
    std::find(cmCacheEntryTypes.begin(), cmCacheEntryTypes.end(), s);
112
0
  if (entry != cmCacheEntryTypes.end()) {
113
0
    type = static_cast<cmStateEnums::CacheEntryType>(
114
0
      entry - cmCacheEntryTypes.begin());
115
0
    return true;
116
0
  }
117
0
  return false;
118
0
}
119
120
bool cmState::IsCacheEntryType(std::string const& key)
121
0
{
122
0
  return std::any_of(
123
0
    cmCacheEntryTypes.begin(), cmCacheEntryTypes.end(),
124
0
    [&key](std::string const& i) -> bool { return key == i; });
125
0
}
126
127
bool cmState::LoadCache(std::string const& path, bool internal,
128
                        std::set<std::string>& excludes,
129
                        std::set<std::string>& includes)
130
0
{
131
0
  return this->CacheManager->LoadCache(path, internal, excludes, includes);
132
0
}
133
134
bool cmState::SaveCache(std::string const& path, cmMessenger* messenger)
135
0
{
136
0
  return this->CacheManager->SaveCache(path, messenger);
137
0
}
138
139
bool cmState::DeleteCache(std::string const& path)
140
0
{
141
0
  return this->CacheManager->DeleteCache(path);
142
0
}
143
144
bool cmState::IsCacheLoaded() const
145
0
{
146
0
  return this->CacheManager->IsCacheLoaded();
147
0
}
148
149
std::vector<std::string> cmState::GetCacheEntryKeys() const
150
0
{
151
0
  return this->CacheManager->GetCacheEntryKeys();
152
0
}
153
154
cmValue cmState::GetCacheEntryValue(std::string const& key) const
155
0
{
156
0
  return this->CacheManager->GetCacheEntryValue(key);
157
0
}
158
159
std::string cmState::GetSafeCacheEntryValue(std::string const& key) const
160
0
{
161
0
  if (cmValue val = this->GetCacheEntryValue(key)) {
162
0
    return *val;
163
0
  }
164
0
  return std::string();
165
0
}
166
167
cmValue cmState::GetInitializedCacheValue(std::string const& key) const
168
3
{
169
3
  return this->CacheManager->GetInitializedCacheValue(key);
170
3
}
171
172
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
173
  std::string const& key) const
174
0
{
175
0
  return this->CacheManager->GetCacheEntryType(key);
176
0
}
177
178
void cmState::SetCacheEntryValue(std::string const& key,
179
                                 std::string const& value)
180
0
{
181
0
  this->CacheManager->SetCacheEntryValue(key, value);
182
0
}
183
184
void cmState::SetCacheEntryProperty(std::string const& key,
185
                                    std::string const& propertyName,
186
                                    std::string const& value)
187
0
{
188
0
  this->CacheManager->SetCacheEntryProperty(key, propertyName, value);
189
0
}
190
191
void cmState::SetCacheEntryBoolProperty(std::string const& key,
192
                                        std::string const& propertyName,
193
                                        bool value)
194
0
{
195
0
  this->CacheManager->SetCacheEntryBoolProperty(key, propertyName, value);
196
0
}
197
198
std::vector<std::string> cmState::GetCacheEntryPropertyList(
199
  std::string const& key)
200
0
{
201
0
  return this->CacheManager->GetCacheEntryPropertyList(key);
202
0
}
203
204
cmValue cmState::GetCacheEntryProperty(std::string const& key,
205
                                       std::string const& propertyName)
206
0
{
207
0
  return this->CacheManager->GetCacheEntryProperty(key, propertyName);
208
0
}
209
210
bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
211
                                          std::string const& propertyName)
212
0
{
213
0
  return this->CacheManager->GetCacheEntryPropertyAsBool(key, propertyName);
214
0
}
215
216
void cmState::AddCacheEntry(std::string const& key, cmValue value,
217
                            std::string const& helpString,
218
                            cmStateEnums::CacheEntryType type)
219
3
{
220
3
  this->CacheManager->AddCacheEntry(key, value, helpString, type);
221
3
}
222
223
bool cmState::DoWriteGlobVerifyTarget() const
224
0
{
225
0
  return this->GlobVerificationManager->DoWriteVerifyTarget();
226
0
}
227
228
std::string const& cmState::GetGlobVerifyScript() const
229
0
{
230
0
  return this->GlobVerificationManager->GetVerifyScript();
231
0
}
232
233
std::string const& cmState::GetGlobVerifyStamp() const
234
0
{
235
0
  return this->GlobVerificationManager->GetVerifyStamp();
236
0
}
237
238
bool cmState::SaveVerificationScript(std::string const& path,
239
                                     cmMessenger* messenger)
240
0
{
241
0
  return this->GlobVerificationManager->SaveVerificationScript(path,
242
0
                                                               messenger);
243
0
}
244
245
void cmState::AddGlobCacheEntry(cmGlobCacheEntry const& entry,
246
                                std::string const& variable,
247
                                cmListFileBacktrace const& backtrace,
248
                                cmMessenger* messenger)
249
0
{
250
0
  this->GlobVerificationManager->AddCacheEntry(entry, variable, backtrace,
251
0
                                               messenger);
252
0
}
253
254
std::vector<cmGlobCacheEntry> cmState::GetGlobCacheEntries() const
255
0
{
256
0
  return this->GlobVerificationManager->GetCacheEntries();
257
0
}
258
259
void cmState::RemoveCacheEntry(std::string const& key)
260
0
{
261
0
  this->CacheManager->RemoveCacheEntry(key);
262
0
}
263
264
void cmState::AppendCacheEntryProperty(std::string const& key,
265
                                       std::string const& property,
266
                                       std::string const& value, bool asString)
267
0
{
268
0
  this->CacheManager->AppendCacheEntryProperty(key, property, value, asString);
269
0
}
270
271
void cmState::RemoveCacheEntryProperty(std::string const& key,
272
                                       std::string const& propertyName)
273
0
{
274
0
  this->CacheManager->RemoveCacheEntryProperty(key, propertyName);
275
0
}
276
277
cmStateSnapshot cmState::Reset()
278
1
{
279
1
  this->GlobalProperties.Clear();
280
1
  this->PropertyDefinitions = {};
281
1
  this->GlobVerificationManager->Reset();
282
283
1
  cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
284
1
  this->ExecutionListFiles.Truncate();
285
286
1
  {
287
1
    cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it =
288
1
      this->BuildsystemDirectory.Truncate();
289
290
1
    cmStateDetail::BuildsystemDirectoryStateType newState;
291
1
    newState.Location = std::move(it->Location);
292
1
    newState.OutputLocation = std::move(it->OutputLocation);
293
1
    newState.CurrentScope = pos;
294
1
    *it = std::move(newState);
295
1
  }
296
297
1
  this->PolicyStack.Clear();
298
1
  pos->Policies = this->PolicyStack.Root();
299
1
  pos->PolicyRoot = this->PolicyStack.Root();
300
1
  pos->PolicyScope = this->PolicyStack.Root();
301
1
  assert(pos->Policies.IsValid());
302
1
  assert(pos->PolicyRoot.IsValid());
303
304
1
  {
305
1
    std::string srcDir =
306
1
      *cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
307
1
    std::string binDir =
308
1
      *cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
309
1
    this->VarTree.Clear();
310
1
    pos->Vars = this->VarTree.Push(this->VarTree.Root());
311
1
    pos->Parent = this->VarTree.Root();
312
1
    pos->Root = this->VarTree.Root();
313
314
1
    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir);
315
1
    pos->Vars->Set("CMAKE_BINARY_DIR", binDir);
316
1
  }
317
318
1
  this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
319
1
                       true);
320
1
  this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::DIRECTORY, "", "",
321
1
                       true);
322
1
  this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY, "", "",
323
1
                       true);
324
325
1
  this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::TARGET, "", "",
326
1
                       true);
327
1
  this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true);
328
1
  this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true);
329
330
1
  return { this, pos };
331
1
}
332
333
void cmState::DefineProperty(std::string const& name,
334
                             cmProperty::ScopeType scope,
335
                             std::string const& ShortDescription,
336
                             std::string const& FullDescription, bool chained,
337
                             std::string const& initializeFromVariable)
338
6
{
339
6
  this->PropertyDefinitions.DefineProperty(name, scope, ShortDescription,
340
6
                                           FullDescription, chained,
341
6
                                           initializeFromVariable);
342
6
}
343
344
cmPropertyDefinition const* cmState::GetPropertyDefinition(
345
  std::string const& name, cmProperty::ScopeType scope) const
346
0
{
347
0
  return this->PropertyDefinitions.GetPropertyDefinition(name, scope);
348
0
}
349
350
bool cmState::IsPropertyChained(std::string const& name,
351
                                cmProperty::ScopeType scope) const
352
0
{
353
0
  if (auto const* def = this->GetPropertyDefinition(name, scope)) {
354
0
    return def->IsChained();
355
0
  }
356
0
  return false;
357
0
}
358
359
void cmState::SetLanguageEnabled(std::string const& l)
360
0
{
361
0
  auto it = std::lower_bound(this->EnabledLanguages.begin(),
362
0
                             this->EnabledLanguages.end(), l);
363
0
  if (it == this->EnabledLanguages.end() || *it != l) {
364
0
    this->EnabledLanguages.insert(it, l);
365
0
  }
366
0
}
367
368
bool cmState::GetLanguageEnabled(std::string const& l) const
369
0
{
370
0
  return std::binary_search(this->EnabledLanguages.begin(),
371
0
                            this->EnabledLanguages.end(), l);
372
0
}
373
374
std::vector<std::string> cmState::GetEnabledLanguages() const
375
0
{
376
0
  return this->EnabledLanguages;
377
0
}
378
379
void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
380
0
{
381
0
  this->EnabledLanguages = langs;
382
0
}
383
384
void cmState::ClearEnabledLanguages()
385
0
{
386
0
  this->EnabledLanguages.clear();
387
0
}
388
389
bool cmState::GetIsGeneratorMultiConfig() const
390
0
{
391
0
  return this->IsGeneratorMultiConfig;
392
0
}
393
394
void cmState::SetIsGeneratorMultiConfig(bool b)
395
1
{
396
1
  this->IsGeneratorMultiConfig = b;
397
1
}
398
399
void cmState::AddBuiltinCommand(std::string const& name, Command command)
400
2.07k
{
401
2.07k
  assert(name == cmSystemTools::LowerCase(name));
402
2.07k
  assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
403
2.07k
  this->BuiltinCommands.emplace(name, std::move(command));
404
2.07k
}
405
406
static bool InvokeBuiltinCommand(cmState::BuiltinCommand command,
407
                                 std::vector<cmListFileArgument> const& args,
408
                                 cmExecutionStatus& status)
409
0
{
410
0
  cmMakefile& mf = status.GetMakefile();
411
0
  std::vector<std::string> expandedArguments;
412
0
  if (!mf.ExpandArguments(args, expandedArguments)) {
413
    // There was an error expanding arguments.  It was already
414
    // reported, so we can skip this command without error.
415
0
    return true;
416
0
  }
417
0
  return command(expandedArguments, status);
418
0
}
419
420
void cmState::AddBuiltinCommand(std::string const& name,
421
                                BuiltinCommand command)
422
1.54k
{
423
1.54k
  this->AddBuiltinCommand(
424
1.54k
    name,
425
1.54k
    [command](std::vector<cmListFileArgument> const& args,
426
1.54k
              cmExecutionStatus& status) -> bool {
427
0
      return InvokeBuiltinCommand(command, args, status);
428
0
    });
429
1.54k
}
430
431
void cmState::AddFlowControlCommand(std::string const& name, Command command)
432
70
{
433
70
  this->FlowControlCommands.insert(name);
434
70
  this->AddBuiltinCommand(name, std::move(command));
435
70
}
436
437
void cmState::AddFlowControlCommand(std::string const& name,
438
                                    BuiltinCommand command)
439
245
{
440
245
  this->FlowControlCommands.insert(name);
441
245
  this->AddBuiltinCommand(name, command);
442
245
}
443
444
void cmState::AddDisallowedCommand(std::string const& name,
445
                                   BuiltinCommand command,
446
                                   cmPolicies::PolicyID policy,
447
                                   char const* message,
448
                                   char const* additionalWarning)
449
35
{
450
35
  this->AddBuiltinCommand(
451
35
    name,
452
35
    [command, policy, message,
453
35
     additionalWarning](std::vector<cmListFileArgument> const& args,
454
35
                        cmExecutionStatus& status) -> bool {
455
0
      cmMakefile& mf = status.GetMakefile();
456
0
      switch (mf.GetPolicyStatus(policy)) {
457
0
        case cmPolicies::WARN: {
458
0
          std::string warning = cmPolicies::GetPolicyWarning(policy);
459
0
          if (additionalWarning) {
460
0
            warning = cmStrCat(warning, '\n', additionalWarning);
461
0
          }
462
0
          mf.IssueMessage(MessageType::AUTHOR_WARNING, warning);
463
0
        }
464
0
          CM_FALLTHROUGH;
465
0
        case cmPolicies::OLD:
466
0
          break;
467
0
        case cmPolicies::NEW:
468
0
          mf.IssueMessage(MessageType::FATAL_ERROR, message);
469
0
          return true;
470
0
      }
471
0
      return InvokeBuiltinCommand(command, args, status);
472
0
    });
473
35
}
474
475
void cmState::AddRemovedCommand(std::string const& name,
476
                                std::string const& message)
477
70
{
478
70
  this->AddBuiltinCommand(name,
479
70
                          [message](std::vector<cmListFileArgument> const&,
480
70
                                    cmExecutionStatus& status) -> bool {
481
0
                            status.GetMakefile().IssueMessage(
482
0
                              MessageType::FATAL_ERROR, message);
483
0
                            return true;
484
0
                          });
485
70
}
486
487
void cmState::AddUnexpectedCommand(std::string const& name, char const* error)
488
329
{
489
329
  this->AddBuiltinCommand(
490
329
    name,
491
329
    [name, error](std::vector<cmListFileArgument> const&,
492
329
                  cmExecutionStatus& status) -> bool {
493
0
      cmValue versionValue =
494
0
        status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
495
0
      if (name == "endif" &&
496
0
          (!versionValue || atof(versionValue->c_str()) <= 1.4)) {
497
0
        return true;
498
0
      }
499
0
      status.SetError(error);
500
0
      return false;
501
0
    });
502
329
}
503
504
void cmState::AddUnexpectedFlowControlCommand(std::string const& name,
505
                                              char const* error)
506
280
{
507
280
  this->FlowControlCommands.insert(name);
508
280
  this->AddUnexpectedCommand(name, error);
509
280
}
510
511
bool cmState::AddScriptedCommand(std::string const& name, BT<Command> command,
512
                                 cmMakefile& mf)
513
0
{
514
0
  std::string sName = cmSystemTools::LowerCase(name);
515
516
0
  if (this->FlowControlCommands.count(sName)) {
517
0
    mf.GetCMakeInstance()->IssueMessage(
518
0
      MessageType::FATAL_ERROR,
519
0
      cmStrCat("Built-in flow control command \"", sName,
520
0
               "\" cannot be overridden."),
521
0
      command.Backtrace);
522
0
    cmSystemTools::SetFatalErrorOccurred();
523
0
    return false;
524
0
  }
525
526
  // if the command already exists, give a new name to the old command.
527
0
  if (Command oldCmd = this->GetCommandByExactName(sName)) {
528
0
    this->ScriptedCommands["_" + sName] = oldCmd;
529
0
  }
530
531
0
  this->ScriptedCommands[sName] = std::move(command.Value);
532
0
  return true;
533
0
}
534
535
cmState::Command cmState::GetCommand(std::string const& name) const
536
0
{
537
0
  return this->GetCommandByExactName(cmSystemTools::LowerCase(name));
538
0
}
539
540
cmState::Command cmState::GetCommandByExactName(std::string const& name) const
541
0
{
542
0
  auto pos = this->ScriptedCommands.find(name);
543
0
  if (pos != this->ScriptedCommands.end()) {
544
0
    return pos->second;
545
0
  }
546
0
  pos = this->BuiltinCommands.find(name);
547
0
  if (pos != this->BuiltinCommands.end()) {
548
0
    return pos->second;
549
0
  }
550
0
  return nullptr;
551
0
}
552
553
std::vector<std::string> cmState::GetCommandNames() const
554
0
{
555
0
  std::vector<std::string> commandNames;
556
0
  commandNames.reserve(this->BuiltinCommands.size() +
557
0
                       this->ScriptedCommands.size());
558
0
  for (auto const& bc : this->BuiltinCommands) {
559
0
    commandNames.push_back(bc.first);
560
0
  }
561
0
  for (auto const& sc : this->ScriptedCommands) {
562
0
    commandNames.push_back(sc.first);
563
0
  }
564
0
  std::sort(commandNames.begin(), commandNames.end());
565
0
  commandNames.erase(std::unique(commandNames.begin(), commandNames.end()),
566
0
                     commandNames.end());
567
0
  return commandNames;
568
0
}
569
570
void cmState::RemoveBuiltinCommand(std::string const& name)
571
0
{
572
0
  assert(name == cmSystemTools::LowerCase(name));
573
0
  this->BuiltinCommands.erase(name);
574
0
}
575
576
void cmState::RemoveUserDefinedCommands()
577
0
{
578
0
  this->ScriptedCommands.clear();
579
0
}
580
581
void cmState::SetGlobalProperty(std::string const& prop,
582
                                std::string const& value)
583
0
{
584
0
  this->GlobalProperties.SetProperty(prop, value);
585
0
}
586
void cmState::SetGlobalProperty(std::string const& prop, cmValue value)
587
0
{
588
0
  this->GlobalProperties.SetProperty(prop, value);
589
0
}
590
591
void cmState::AppendGlobalProperty(std::string const& prop,
592
                                   std::string const& value, bool asString)
593
0
{
594
0
  this->GlobalProperties.AppendProperty(prop, value, asString);
595
0
}
596
597
cmValue cmState::GetGlobalProperty(std::string const& prop)
598
0
{
599
0
  if (prop == "CACHE_VARIABLES") {
600
0
    std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
601
0
    this->SetGlobalProperty("CACHE_VARIABLES", cmList::to_string(cacheKeys));
602
0
  } else if (prop == "COMMANDS") {
603
0
    std::vector<std::string> commands = this->GetCommandNames();
604
0
    this->SetGlobalProperty("COMMANDS", cmList::to_string(commands));
605
0
  } else if (prop == "IN_TRY_COMPILE") {
606
0
    this->SetGlobalProperty("IN_TRY_COMPILE",
607
0
                            this->IsTryCompile == TryCompile::Yes ? "1" : "0");
608
0
  } else if (prop == "GENERATOR_IS_MULTI_CONFIG") {
609
0
    this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
610
0
                            this->IsGeneratorMultiConfig ? "1" : "0");
611
0
  } else if (prop == "ENABLED_LANGUAGES") {
612
0
    auto langs = cmList::to_string(this->EnabledLanguages);
613
0
    this->SetGlobalProperty("ENABLED_LANGUAGES", langs);
614
0
  } else if (prop == "CMAKE_ROLE") {
615
0
    this->SetGlobalProperty("CMAKE_ROLE", this->GetRoleString());
616
0
  }
617
0
#define STRING_LIST_ELEMENT(F) ";" #F
618
0
  if (prop == "CMAKE_C_KNOWN_FEATURES") {
619
0
    static std::string const s_out(
620
0
      &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]);
621
0
    return cmValue(s_out);
622
0
  }
623
0
  if (prop == "CMAKE_C90_KNOWN_FEATURES") {
624
0
    static std::string const s_out(
625
0
      &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]);
626
0
    return cmValue(s_out);
627
0
  }
628
0
  if (prop == "CMAKE_C99_KNOWN_FEATURES") {
629
0
    static std::string const s_out(
630
0
      &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]);
631
0
    return cmValue(s_out);
632
0
  }
633
0
  if (prop == "CMAKE_C11_KNOWN_FEATURES") {
634
0
    static std::string const s_out(
635
0
      &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]);
636
0
    return cmValue(s_out);
637
0
  }
638
0
  if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
639
0
    static std::string const s_out(
640
0
      &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]);
641
0
    return cmValue(s_out);
642
0
  }
643
0
  if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
644
0
    static std::string const s_out(
645
0
      &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]);
646
0
    return cmValue(s_out);
647
0
  }
648
0
  if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
649
0
    static std::string const s_out(
650
0
      &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]);
651
0
    return cmValue(s_out);
652
0
  }
653
0
  if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
654
0
    static std::string const s_out(
655
0
      &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]);
656
0
    return cmValue(s_out);
657
0
  }
658
0
  if (prop == "CMAKE_CUDA_KNOWN_FEATURES") {
659
0
    static std::string const s_out(
660
0
      &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]);
661
0
    return cmValue(s_out);
662
0
  }
663
0
  if (prop == "CMAKE_HIP_KNOWN_FEATURES") {
664
0
    static std::string const s_out(
665
0
      &FOR_EACH_HIP_FEATURE(STRING_LIST_ELEMENT)[1]);
666
0
    return cmValue(s_out);
667
0
  }
668
669
0
#undef STRING_LIST_ELEMENT
670
0
  return this->GlobalProperties.GetPropertyValue(prop);
671
0
}
672
673
bool cmState::GetGlobalPropertyAsBool(std::string const& prop)
674
0
{
675
0
  return this->GetGlobalProperty(prop).IsOn();
676
0
}
677
678
void cmState::SetSourceDirectory(std::string const& sourceDirectory)
679
36
{
680
36
  this->SourceDirectory = sourceDirectory;
681
36
  cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
682
36
}
683
684
std::string const& cmState::GetSourceDirectory() const
685
72
{
686
72
  return this->SourceDirectory;
687
72
}
688
689
void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
690
36
{
691
36
  this->BinaryDirectory = binaryDirectory;
692
36
  cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
693
36
}
694
695
void cmState::SetWindowsShell(bool windowsShell)
696
1
{
697
1
  this->WindowsShell = windowsShell;
698
1
}
699
700
bool cmState::UseWindowsShell() const
701
0
{
702
0
  return this->WindowsShell;
703
0
}
704
705
void cmState::SetWindowsVSIDE(bool windowsVSIDE)
706
1
{
707
1
  this->WindowsVSIDE = windowsVSIDE;
708
1
}
709
710
bool cmState::UseWindowsVSIDE() const
711
0
{
712
0
  return this->WindowsVSIDE;
713
0
}
714
715
void cmState::SetGhsMultiIDE(bool ghsMultiIDE)
716
0
{
717
0
  this->GhsMultiIDE = ghsMultiIDE;
718
0
}
719
720
bool cmState::UseGhsMultiIDE() const
721
0
{
722
0
  return this->GhsMultiIDE;
723
0
}
724
725
void cmState::SetBorlandMake(bool borlandMake)
726
0
{
727
0
  this->BorlandMake = borlandMake;
728
0
}
729
730
bool cmState::UseBorlandMake() const
731
0
{
732
0
  return this->BorlandMake;
733
0
}
734
735
void cmState::SetWatcomWMake(bool watcomWMake)
736
1
{
737
1
  this->WatcomWMake = watcomWMake;
738
1
}
739
740
bool cmState::UseWatcomWMake() const
741
0
{
742
0
  return this->WatcomWMake;
743
0
}
744
745
void cmState::SetMinGWMake(bool minGWMake)
746
1
{
747
1
  this->MinGWMake = minGWMake;
748
1
}
749
750
bool cmState::UseMinGWMake() const
751
0
{
752
0
  return this->MinGWMake;
753
0
}
754
755
void cmState::SetNMake(bool nMake)
756
1
{
757
1
  this->NMake = nMake;
758
1
}
759
760
bool cmState::UseNMake() const
761
0
{
762
0
  return this->NMake;
763
0
}
764
765
void cmState::SetMSYSShell(bool mSYSShell)
766
1
{
767
1
  this->MSYSShell = mSYSShell;
768
1
}
769
770
bool cmState::UseMSYSShell() const
771
0
{
772
0
  return this->MSYSShell;
773
0
}
774
775
void cmState::SetNinja(bool ninja)
776
0
{
777
0
  this->Ninja = ninja;
778
0
}
779
780
bool cmState::UseNinja() const
781
0
{
782
0
  return this->Ninja;
783
0
}
784
785
void cmState::SetNinjaMulti(bool ninjaMulti)
786
0
{
787
0
  this->NinjaMulti = ninjaMulti;
788
0
}
789
790
bool cmState::UseNinjaMulti() const
791
0
{
792
0
  return this->NinjaMulti;
793
0
}
794
795
void cmState::SetFastbuildMake(bool fastbuildMake)
796
1
{
797
1
  this->FastbuildMake = fastbuildMake;
798
1
}
799
800
bool cmState::UseFastbuildMake() const
801
0
{
802
0
  return this->FastbuildMake;
803
0
}
804
805
unsigned int cmState::GetCacheMajorVersion() const
806
0
{
807
0
  return this->CacheManager->GetCacheMajorVersion();
808
0
}
809
810
unsigned int cmState::GetCacheMinorVersion() const
811
0
{
812
0
  return this->CacheManager->GetCacheMinorVersion();
813
0
}
814
815
void cmState::SetRoleToProjectForCMakeBuildVsReconfigure()
816
0
{
817
0
  this->StateRole = Role::Project;
818
0
}
819
820
void cmState::SetRoleToHelpForListPresets()
821
0
{
822
0
  this->StateRole = Role::Help;
823
0
}
824
825
cmState::Role cmState::GetRole() const
826
76
{
827
76
  return this->StateRole;
828
76
}
829
830
std::string cmState::GetRoleString() const
831
0
{
832
0
  return RoleToString(this->StateRole);
833
0
}
834
835
std::string cmState::RoleToString(cmState::Role mode)
836
0
{
837
0
  switch (mode) {
838
0
    case Role::Project:
839
0
      return "PROJECT";
840
0
    case Role::Script:
841
0
      return "SCRIPT";
842
0
    case Role::FindPackage:
843
0
      return "FIND_PACKAGE";
844
0
    case Role::CTest:
845
0
      return "CTEST";
846
0
    case Role::CPack:
847
0
      return "CPACK";
848
0
    case Role::Help:
849
0
      return "HELP";
850
0
    case Role::Internal:
851
0
      return "INTERNAL";
852
0
  }
853
0
  return "UNKNOWN";
854
0
}
855
856
cmState::TryCompile cmState::GetIsTryCompile() const
857
36
{
858
36
  return this->IsTryCompile;
859
36
}
860
861
std::string const& cmState::GetBinaryDirectory() const
862
36
{
863
36
  return this->BinaryDirectory;
864
36
}
865
866
cmStateSnapshot cmState::CreateBaseSnapshot()
867
35
{
868
35
  cmStateDetail::PositionType pos =
869
35
    this->SnapshotData.Push(this->SnapshotData.Root());
870
35
  pos->DirectoryParent = this->SnapshotData.Root();
871
35
  pos->ScopeParent = this->SnapshotData.Root();
872
35
  pos->SnapshotType = cmStateEnums::BaseType;
873
35
  pos->Keep = true;
874
35
  pos->BuildSystemDirectory =
875
35
    this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
876
35
  pos->ExecutionListFile =
877
35
    this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
878
35
  pos->IncludeDirectoryPosition = 0;
879
35
  pos->CompileDefinitionsPosition = 0;
880
35
  pos->CompileOptionsPosition = 0;
881
35
  pos->LinkOptionsPosition = 0;
882
35
  pos->LinkDirectoriesPosition = 0;
883
35
  pos->BuildSystemDirectory->CurrentScope = pos;
884
35
  pos->Policies = this->PolicyStack.Root();
885
35
  pos->PolicyRoot = this->PolicyStack.Root();
886
35
  pos->PolicyScope = this->PolicyStack.Root();
887
35
  assert(pos->Policies.IsValid());
888
35
  assert(pos->PolicyRoot.IsValid());
889
35
  pos->Vars = this->VarTree.Push(this->VarTree.Root());
890
35
  assert(pos->Vars.IsValid());
891
35
  pos->Parent = this->VarTree.Root();
892
35
  pos->Root = this->VarTree.Root();
893
35
  return { this, pos };
894
35
}
895
896
cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot(
897
  cmStateSnapshot const& originSnapshot)
898
0
{
899
0
  assert(originSnapshot.IsValid());
900
0
  cmStateDetail::PositionType pos =
901
0
    this->SnapshotData.Push(originSnapshot.Position);
902
0
  pos->DirectoryParent = originSnapshot.Position;
903
0
  pos->ScopeParent = originSnapshot.Position;
904
0
  pos->SnapshotType = cmStateEnums::BuildsystemDirectoryType;
905
0
  pos->Keep = true;
906
0
  pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
907
0
    originSnapshot.Position->BuildSystemDirectory);
908
0
  pos->ExecutionListFile =
909
0
    this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
910
0
  pos->BuildSystemDirectory->CurrentScope = pos;
911
0
  pos->Policies = originSnapshot.Position->Policies;
912
0
  pos->PolicyRoot = originSnapshot.Position->Policies;
913
0
  pos->PolicyScope = originSnapshot.Position->Policies;
914
0
  assert(pos->Policies.IsValid());
915
0
  assert(pos->PolicyRoot.IsValid());
916
917
0
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
918
0
  pos->Parent = origin;
919
0
  pos->Root = origin;
920
0
  pos->Vars = this->VarTree.Push(origin);
921
922
0
  cmStateSnapshot snapshot = cmStateSnapshot(this, pos);
923
0
  originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
924
0
  snapshot.SetDefaultDefinitions();
925
0
  snapshot.InitializeFromParent();
926
0
  snapshot.SetDirectoryDefinitions();
927
0
  return snapshot;
928
0
}
929
930
cmStateSnapshot cmState::CreateDeferCallSnapshot(
931
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
932
0
{
933
0
  cmStateDetail::PositionType pos =
934
0
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
935
0
  pos->SnapshotType = cmStateEnums::DeferCallType;
936
0
  pos->Keep = false;
937
0
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
938
0
    originSnapshot.Position->ExecutionListFile, fileName);
939
0
  assert(originSnapshot.Position->Vars.IsValid());
940
0
  pos->BuildSystemDirectory->CurrentScope = pos;
941
0
  pos->PolicyScope = originSnapshot.Position->Policies;
942
0
  return { this, pos };
943
0
}
944
945
cmStateSnapshot cmState::CreateFunctionCallSnapshot(
946
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
947
0
{
948
0
  cmStateDetail::PositionType pos =
949
0
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
950
0
  pos->ScopeParent = originSnapshot.Position;
951
0
  pos->SnapshotType = cmStateEnums::FunctionCallType;
952
0
  pos->Keep = false;
953
0
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
954
0
    originSnapshot.Position->ExecutionListFile, fileName);
955
0
  pos->BuildSystemDirectory->CurrentScope = pos;
956
0
  pos->PolicyScope = originSnapshot.Position->Policies;
957
0
  assert(originSnapshot.Position->Vars.IsValid());
958
0
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
959
0
  pos->Parent = origin;
960
0
  pos->Vars = this->VarTree.Push(origin);
961
0
  return { this, pos };
962
0
}
963
964
cmStateSnapshot cmState::CreateMacroCallSnapshot(
965
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
966
0
{
967
0
  cmStateDetail::PositionType pos =
968
0
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
969
0
  pos->SnapshotType = cmStateEnums::MacroCallType;
970
0
  pos->Keep = false;
971
0
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
972
0
    originSnapshot.Position->ExecutionListFile, fileName);
973
0
  assert(originSnapshot.Position->Vars.IsValid());
974
0
  pos->BuildSystemDirectory->CurrentScope = pos;
975
0
  pos->PolicyScope = originSnapshot.Position->Policies;
976
0
  return { this, pos };
977
0
}
978
979
cmStateSnapshot cmState::CreateIncludeFileSnapshot(
980
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
981
0
{
982
0
  cmStateDetail::PositionType pos =
983
0
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
984
0
  pos->SnapshotType = cmStateEnums::IncludeFileType;
985
0
  pos->Keep = true;
986
0
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
987
0
    originSnapshot.Position->ExecutionListFile, fileName);
988
0
  assert(originSnapshot.Position->Vars.IsValid());
989
0
  pos->BuildSystemDirectory->CurrentScope = pos;
990
0
  pos->PolicyScope = originSnapshot.Position->Policies;
991
0
  return { this, pos };
992
0
}
993
994
cmStateSnapshot cmState::CreateVariableScopeSnapshot(
995
  cmStateSnapshot const& originSnapshot)
996
0
{
997
0
  cmStateDetail::PositionType pos =
998
0
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
999
0
  pos->ScopeParent = originSnapshot.Position;
1000
0
  pos->SnapshotType = cmStateEnums::VariableScopeType;
1001
0
  pos->Keep = false;
1002
0
  pos->BuildSystemDirectory->CurrentScope = pos;
1003
0
  pos->PolicyScope = originSnapshot.Position->Policies;
1004
0
  assert(originSnapshot.Position->Vars.IsValid());
1005
1006
0
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
1007
0
  pos->Parent = origin;
1008
0
  pos->Vars = this->VarTree.Push(origin);
1009
0
  assert(pos->Vars.IsValid());
1010
0
  return { this, pos };
1011
0
}
1012
1013
cmStateSnapshot cmState::CreateInlineListFileSnapshot(
1014
  cmStateSnapshot const& originSnapshot, std::string const& fileName)
1015
1
{
1016
1
  cmStateDetail::PositionType pos =
1017
1
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
1018
1
  pos->SnapshotType = cmStateEnums::InlineListFileType;
1019
1
  pos->Keep = true;
1020
1
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
1021
1
    originSnapshot.Position->ExecutionListFile, fileName);
1022
1
  pos->BuildSystemDirectory->CurrentScope = pos;
1023
1
  pos->PolicyScope = originSnapshot.Position->Policies;
1024
1
  return { this, pos };
1025
1
}
1026
1027
cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
1028
  cmStateSnapshot const& originSnapshot)
1029
1
{
1030
1
  cmStateDetail::PositionType pos =
1031
1
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
1032
1
  pos->SnapshotType = cmStateEnums::PolicyScopeType;
1033
1
  pos->Keep = false;
1034
1
  pos->BuildSystemDirectory->CurrentScope = pos;
1035
1
  pos->PolicyScope = originSnapshot.Position->Policies;
1036
1
  return { this, pos };
1037
1
}
1038
1039
cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot)
1040
1
{
1041
1
  cmStateDetail::PositionType pos = originSnapshot.Position;
1042
1
  cmStateDetail::PositionType prevPos = pos;
1043
1
  ++prevPos;
1044
1
  prevPos->IncludeDirectoryPosition =
1045
1
    prevPos->BuildSystemDirectory->IncludeDirectories.size();
1046
1
  prevPos->CompileDefinitionsPosition =
1047
1
    prevPos->BuildSystemDirectory->CompileDefinitions.size();
1048
1
  prevPos->CompileOptionsPosition =
1049
1
    prevPos->BuildSystemDirectory->CompileOptions.size();
1050
1
  prevPos->LinkOptionsPosition =
1051
1
    prevPos->BuildSystemDirectory->LinkOptions.size();
1052
1
  prevPos->LinkDirectoriesPosition =
1053
1
    prevPos->BuildSystemDirectory->LinkDirectories.size();
1054
1
  prevPos->BuildSystemDirectory->CurrentScope = prevPos;
1055
1
  prevPos->UnwindState = pos->UnwindState;
1056
1057
1
  if (!pos->Keep && this->SnapshotData.IsLast(pos)) {
1058
0
    if (pos->Vars != prevPos->Vars) {
1059
0
      assert(this->VarTree.IsLast(pos->Vars));
1060
0
      this->VarTree.Pop(pos->Vars);
1061
0
    }
1062
0
    if (pos->ExecutionListFile != prevPos->ExecutionListFile) {
1063
0
      assert(this->ExecutionListFiles.IsLast(pos->ExecutionListFile));
1064
0
      this->ExecutionListFiles.Pop(pos->ExecutionListFile);
1065
0
    }
1066
0
    this->SnapshotData.Pop(pos);
1067
0
  }
1068
1069
1
  return { this, prevPos };
1070
1
}
1071
1072
static bool ParseEntryWithoutType(std::string const& entry, std::string& var,
1073
                                  std::string& value)
1074
0
{
1075
  // input line is:         key=value
1076
0
  static cmsys::RegularExpression reg(
1077
0
    "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1078
  // input line is:         "key"=value
1079
0
  static cmsys::RegularExpression regQuoted(
1080
0
    "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1081
0
  bool flag = false;
1082
0
  if (regQuoted.find(entry)) {
1083
0
    var = regQuoted.match(1);
1084
0
    value = regQuoted.match(2);
1085
0
    flag = true;
1086
0
  } else if (reg.find(entry)) {
1087
0
    var = reg.match(1);
1088
0
    value = reg.match(2);
1089
0
    flag = true;
1090
0
  }
1091
1092
  // if value is enclosed in single quotes ('foo') then remove them
1093
  // it is used to enclose trailing space or tab
1094
0
  if (flag && value.size() >= 2 && value.front() == '\'' &&
1095
0
      value.back() == '\'') {
1096
0
    value = value.substr(1, value.size() - 2);
1097
0
  }
1098
1099
0
  return flag;
1100
0
}
1101
1102
bool cmState::ParseCacheEntry(std::string const& entry, std::string& var,
1103
                              std::string& value,
1104
                              cmStateEnums::CacheEntryType& type)
1105
0
{
1106
  // input line is:         key:type=value
1107
0
  static cmsys::RegularExpression reg(
1108
0
    "^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1109
  // input line is:         "key":type=value
1110
0
  static cmsys::RegularExpression regQuoted(
1111
0
    "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1112
0
  bool flag = false;
1113
0
  if (regQuoted.find(entry)) {
1114
0
    var = regQuoted.match(1);
1115
0
    type = cmState::StringToCacheEntryType(regQuoted.match(2));
1116
0
    value = regQuoted.match(3);
1117
0
    flag = true;
1118
0
  } else if (reg.find(entry)) {
1119
0
    var = reg.match(1);
1120
0
    type = cmState::StringToCacheEntryType(reg.match(2));
1121
0
    value = reg.match(3);
1122
0
    flag = true;
1123
0
  }
1124
1125
  // if value is enclosed in single quotes ('foo') then remove them
1126
  // it is used to enclose trailing space or tab
1127
0
  if (flag && value.size() >= 2 && value.front() == '\'' &&
1128
0
      value.back() == '\'') {
1129
0
    value = value.substr(1, value.size() - 2);
1130
0
  }
1131
1132
0
  if (!flag) {
1133
0
    return ParseEntryWithoutType(entry, var, value);
1134
0
  }
1135
1136
0
  return flag;
1137
0
}
1138
1139
cmState::Command cmState::GetDependencyProviderCommand(
1140
  cmDependencyProvider::Method method) const
1141
0
{
1142
0
  return (this->DependencyProvider &&
1143
0
          this->DependencyProvider->SupportsMethod(method))
1144
0
    ? this->GetCommand(this->DependencyProvider->GetCommand())
1145
0
    : Command{};
1146
0
}