cmState.cxx 56.6 KB
Newer Older
1
2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
Stephen Kelly's avatar
Stephen Kelly committed
3
4
#include "cmState.h"

5
#include "cmAlgorithms.h"
6
#include "cmCacheManager.h"
7
#include "cmCommand.h"
8
#include "cmDefinitions.h"
9
10
11
#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmTypeMacro.h"
12
13
#include "cmVersion.h"
#include "cmake.h"
14

15
#include <algorithm>
16
#include <assert.h>
17
18
19
20
21
#include <cmsys/RegularExpression.hxx>
#include <iterator>
#include <stdio.h>
#include <string.h>
#include <utility>
Stephen Kelly's avatar
Stephen Kelly committed
22

23
static std::string const kBINARY_DIR = "BINARY_DIR";
24
static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS";
25
static std::string const kSOURCE_DIR = "SOURCE_DIR";
26
27
static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES";

28
struct cmStateDetail::SnapshotDataType
29
{
30
31
  cmStateDetail::PositionType ScopeParent;
  cmStateDetail::PositionType DirectoryParent;
32
33
34
  cmLinkedTree<cmStateDetail::PolicyStackEntry>::iterator Policies;
  cmLinkedTree<cmStateDetail::PolicyStackEntry>::iterator PolicyRoot;
  cmLinkedTree<cmStateDetail::PolicyStackEntry>::iterator PolicyScope;
35
  cmStateEnums::SnapshotType SnapshotType;
36
  bool Keep;
37
  cmLinkedTree<std::string>::iterator ExecutionListFile;
38
  cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator
39
    BuildSystemDirectory;
40
41
42
  cmLinkedTree<cmDefinitions>::iterator Vars;
  cmLinkedTree<cmDefinitions>::iterator Root;
  cmLinkedTree<cmDefinitions>::iterator Parent;
43
44
45
  std::vector<std::string>::size_type IncludeDirectoryPosition;
  std::vector<std::string>::size_type CompileDefinitionsPosition;
  std::vector<std::string>::size_type CompileOptionsPosition;
46
47
};

48
struct cmStateDetail::PolicyStackEntry : public cmPolicies::PolicyMap
49
50
{
  typedef cmPolicies::PolicyMap derived;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  PolicyStackEntry(bool w = false)
    : derived()
    , Weak(w)
  {
  }
  PolicyStackEntry(derived const& d, bool w)
    : derived(d)
    , Weak(w)
  {
  }
  PolicyStackEntry(PolicyStackEntry const& r)
    : derived(r)
    , Weak(r.Weak)
  {
  }
66
67
68
  bool Weak;
};

69
struct cmStateDetail::BuildsystemDirectoryStateType
70
{
71
  cmStateDetail::PositionType DirectoryEnd;
72

73
74
75
76
77
78
79
80
81
82
  std::string Location;
  std::string OutputLocation;

  // The top-most directories for relative path conversion.  Both the
  // source and destination location of a relative path conversion
  // must be underneath one of these directories (both under source or
  // both under binary) in order for the relative path to be evaluated
  // safely by the build tools.
  std::string RelativePathTopSource;
  std::string RelativePathTopBinary;
83
84
85
86
87
88
89
90
91

  std::vector<std::string> IncludeDirectories;
  std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces;

  std::vector<std::string> CompileDefinitions;
  std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;

  std::vector<std::string> CompileOptions;
  std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
92

93
94
  std::vector<std::string> NormalTargetNames;

95
96
  std::string ProjectName;

97
  cmPropertyMap Properties;
98
99

  std::vector<cmState::Snapshot> Children;
100
101
};

102
cmState::cmState()
103
104
105
106
107
108
109
  : IsInTryCompile(false)
  , WindowsShell(false)
  , WindowsVSIDE(false)
  , WatcomWMake(false)
  , MinGWMake(false)
  , NMake(false)
  , MSYSShell(false)
Stephen Kelly's avatar
Stephen Kelly committed
110
{
111
  this->CacheManager = new cmCacheManager;
Stephen Kelly's avatar
Stephen Kelly committed
112
}
113

114
115
cmState::~cmState()
{
116
  delete this->CacheManager;
117
118
119
  cmDeleteAll(this->Commands);
}

120
const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
121
{
122
  switch (targetType) {
123
    case cmStateEnums::STATIC_LIBRARY:
124
      return "STATIC_LIBRARY";
125
    case cmStateEnums::MODULE_LIBRARY:
126
      return "MODULE_LIBRARY";
127
    case cmStateEnums::SHARED_LIBRARY:
128
      return "SHARED_LIBRARY";
129
    case cmStateEnums::OBJECT_LIBRARY:
130
      return "OBJECT_LIBRARY";
131
    case cmStateEnums::EXECUTABLE:
132
      return "EXECUTABLE";
133
    case cmStateEnums::UTILITY:
134
      return "UTILITY";
135
    case cmStateEnums::GLOBAL_TARGET:
136
      return "GLOBAL_TARGET";
137
    case cmStateEnums::INTERFACE_LIBRARY:
138
      return "INTERFACE_LIBRARY";
139
    case cmStateEnums::UNKNOWN_LIBRARY:
140
141
      return "UNKNOWN_LIBRARY";
  }
142
  assert(0 && "Unexpected target type");
Daniel Pfeifer's avatar
Daniel Pfeifer committed
143
  return CM_NULLPTR;
144
145
}

146
147
const char* cmCacheEntryTypes[] = { "BOOL",          "PATH",     "FILEPATH",
                                    "STRING",        "INTERNAL", "STATIC",
Daniel Pfeifer's avatar
Daniel Pfeifer committed
148
                                    "UNINITIALIZED", CM_NULLPTR };
149

150
const char* cmState::CacheEntryTypeToString(cmStateEnums::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
151
{
152
  if (type > 6) {
153
    return cmCacheEntryTypes[6];
154
  }
155
  return cmCacheEntryTypes[type];
Stephen Kelly's avatar
Stephen Kelly committed
156
157
}

158
cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(const char* s)
Stephen Kelly's avatar
Stephen Kelly committed
159
{
160
  int i = 0;
161
162
  while (cmCacheEntryTypes[i]) {
    if (strcmp(s, cmCacheEntryTypes[i]) == 0) {
163
      return static_cast<cmStateEnums::CacheEntryType>(i);
164
    }
165
166
    ++i;
  }
167
  return cmStateEnums::STRING;
Stephen Kelly's avatar
Stephen Kelly committed
168
169
170
171
}

bool cmState::IsCacheEntryType(std::string const& key)
{
172
173
  for (int i = 0; cmCacheEntryTypes[i]; ++i) {
    if (strcmp(key.c_str(), cmCacheEntryTypes[i]) == 0) {
174
175
      return true;
    }
176
  }
177
  return false;
Stephen Kelly's avatar
Stephen Kelly committed
178
179
}

180
181
182
183
bool cmState::LoadCache(const std::string& path, bool internal,
                        std::set<std::string>& excludes,
                        std::set<std::string>& includes)
{
184
  return this->CacheManager->LoadCache(path, internal, excludes, includes);
185
186
187
188
}

bool cmState::SaveCache(const std::string& path)
{
189
  return this->CacheManager->SaveCache(path);
190
191
192
193
}

bool cmState::DeleteCache(const std::string& path)
{
194
  return this->CacheManager->DeleteCache(path);
195
196
}

Stephen Kelly's avatar
Stephen Kelly committed
197
198
199
std::vector<std::string> cmState::GetCacheEntryKeys() const
{
  std::vector<std::string> definitions;
200
  definitions.reserve(this->CacheManager->GetSize());
201
202
  cmCacheManager::CacheIterator cit = this->CacheManager->GetCacheIterator();
  for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
Stephen Kelly's avatar
Stephen Kelly committed
203
    definitions.push_back(cit.GetName());
204
  }
Stephen Kelly's avatar
Stephen Kelly committed
205
206
207
208
209
  return definitions;
}

const char* cmState::GetCacheEntryValue(std::string const& key) const
{
210
211
  cmCacheManager::CacheEntry* e = this->CacheManager->GetCacheEntry(key);
  if (!e) {
Daniel Pfeifer's avatar
Daniel Pfeifer committed
212
    return CM_NULLPTR;
213
  }
Stephen Kelly's avatar
Stephen Kelly committed
214
215
216
  return e->Value.c_str();
}

217
const char* cmState::GetInitializedCacheValue(std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
218
{
219
  return this->CacheManager->GetInitializedCacheValue(key);
Stephen Kelly's avatar
Stephen Kelly committed
220
221
}

222
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
223
  std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
224
225
{
  cmCacheManager::CacheIterator it =
226
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
227
228
229
230
  return it.GetType();
}

void cmState::SetCacheEntryValue(std::string const& key,
231
                                 std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
232
{
233
  this->CacheManager->SetCacheEntryValue(key, value);
Stephen Kelly's avatar
Stephen Kelly committed
234
235
236
}

void cmState::SetCacheEntryProperty(std::string const& key,
237
238
                                    std::string const& propertyName,
                                    std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
239
240
{
  cmCacheManager::CacheIterator it =
241
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
242
243
244
245
  it.SetProperty(propertyName, value.c_str());
}

void cmState::SetCacheEntryBoolProperty(std::string const& key,
246
247
                                        std::string const& propertyName,
                                        bool value)
Stephen Kelly's avatar
Stephen Kelly committed
248
249
{
  cmCacheManager::CacheIterator it =
250
    this->CacheManager->GetCacheIterator(key.c_str());
Stephen Kelly's avatar
Stephen Kelly committed
251
252
253
  it.SetProperty(propertyName, value);
}

254
255
256
257
258
259
260
261
std::vector<std::string> cmState::GetCacheEntryPropertyList(
  const std::string& key)
{
  cmCacheManager::CacheIterator it =
    this->CacheManager->GetCacheIterator(key.c_str());
  return it.GetPropertyList();
}

Stephen Kelly's avatar
Stephen Kelly committed
262
const char* cmState::GetCacheEntryProperty(std::string const& key,
263
                                           std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
264
{
265
266
267
  cmCacheManager::CacheIterator it =
    this->CacheManager->GetCacheIterator(key.c_str());
  if (!it.PropertyExists(propertyName)) {
Daniel Pfeifer's avatar
Daniel Pfeifer committed
268
    return CM_NULLPTR;
269
  }
Stephen Kelly's avatar
Stephen Kelly committed
270
271
272
273
  return it.GetProperty(propertyName);
}

bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
274
                                          std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
275
{
276
277
  return this->CacheManager->GetCacheIterator(key.c_str())
    .GetPropertyAsBool(propertyName);
Stephen Kelly's avatar
Stephen Kelly committed
278
279
280
}

void cmState::AddCacheEntry(const std::string& key, const char* value,
281
                            const char* helpString,
282
                            cmStateEnums::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
283
{
284
  this->CacheManager->AddCacheEntry(key, value, helpString, type);
Stephen Kelly's avatar
Stephen Kelly committed
285
286
287
288
}

void cmState::RemoveCacheEntry(std::string const& key)
{
289
  this->CacheManager->RemoveCacheEntry(key);
Stephen Kelly's avatar
Stephen Kelly committed
290
291
292
}

void cmState::AppendCacheEntryProperty(const std::string& key,
293
294
                                       const std::string& property,
                                       const std::string& value, bool asString)
Stephen Kelly's avatar
Stephen Kelly committed
295
{
296
297
  this->CacheManager->GetCacheIterator(key.c_str())
    .AppendProperty(property, value.c_str(), asString);
Stephen Kelly's avatar
Stephen Kelly committed
298
299
300
}

void cmState::RemoveCacheEntryProperty(std::string const& key,
301
                                       std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
302
{
303
  this->CacheManager->GetCacheIterator(key.c_str())
Daniel Pfeifer's avatar
Daniel Pfeifer committed
304
    .SetProperty(propertyName, (void*)CM_NULLPTR);
Stephen Kelly's avatar
Stephen Kelly committed
305
}
306

307
cmState::Snapshot cmState::Reset()
308
{
309
  this->GlobalProperties.clear();
310
  this->PropertyDefinitions.clear();
311

312
  cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
313
314
  this->ExecutionListFiles.Truncate();

315
  {
316
    cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it =
317
      this->BuildsystemDirectory.Truncate();
318
319
320
321
322
323
324
    it->IncludeDirectories.clear();
    it->IncludeDirectoryBacktraces.clear();
    it->CompileDefinitions.clear();
    it->CompileDefinitionsBacktraces.clear();
    it->CompileOptions.clear();
    it->CompileOptionsBacktraces.clear();
    it->DirectoryEnd = pos;
325
    it->NormalTargetNames.clear();
326
327
    it->Properties.clear();
    it->Children.clear();
328
  }
329

330
331
332
333
334
335
  this->PolicyStack.Clear();
  pos->Policies = this->PolicyStack.Root();
  pos->PolicyRoot = this->PolicyStack.Root();
  pos->PolicyScope = this->PolicyStack.Root();
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
336
337

  {
338
    std::string srcDir =
339
      cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
340
    std::string binDir =
341
      cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
342
343
344
345
    this->VarTree.Clear();
    pos->Vars = this->VarTree.Push(this->VarTree.Root());
    pos->Parent = this->VarTree.Root();
    pos->Root = this->VarTree.Root();
346

347
348
    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
    pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
349
350
  }

351
352
353
354
355
356
357
358
359
360
361
  this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
                       true);
  this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::DIRECTORY, "", "",
                       true);
  this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY, "", "",
                       true);

  this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::TARGET, "", "",
                       true);
  this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true);
  this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true);
362
363

  return Snapshot(this, pos);
364
365
366
}

void cmState::DefineProperty(const std::string& name,
367
368
369
                             cmProperty::ScopeType scope,
                             const char* ShortDescription,
                             const char* FullDescription, bool chained)
370
{
371
372
  this->PropertyDefinitions[scope].DefineProperty(
    name, scope, ShortDescription, FullDescription, chained);
373
374
}

375
376
cmPropertyDefinition const* cmState::GetPropertyDefinition(
  const std::string& name, cmProperty::ScopeType scope) const
377
{
378
  if (this->IsPropertyDefined(name, scope)) {
379
    cmPropertyDefinitionMap const& defs =
380
      this->PropertyDefinitions.find(scope)->second;
381
    return &defs.find(name)->second;
382
  }
Daniel Pfeifer's avatar
Daniel Pfeifer committed
383
  return CM_NULLPTR;
384
385
386
}

bool cmState::IsPropertyDefined(const std::string& name,
387
                                cmProperty::ScopeType scope) const
388
{
389
390
391
  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
    this->PropertyDefinitions.find(scope);
  if (it == this->PropertyDefinitions.end()) {
392
    return false;
393
  }
394
  return it->second.IsPropertyDefined(name);
395
396
397
}

bool cmState::IsPropertyChained(const std::string& name,
398
                                cmProperty::ScopeType scope) const
399
{
400
401
402
  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
    this->PropertyDefinitions.find(scope);
  if (it == this->PropertyDefinitions.end()) {
403
    return false;
404
  }
405
  return it->second.IsPropertyChained(name);
406
}
407
408
409

void cmState::SetLanguageEnabled(std::string const& l)
{
410
411
412
  std::vector<std::string>::iterator it = std::lower_bound(
    this->EnabledLanguages.begin(), this->EnabledLanguages.end(), l);
  if (it == this->EnabledLanguages.end() || *it != l) {
413
    this->EnabledLanguages.insert(it, l);
414
  }
415
416
417
418
419
420
421
422
423
424
425
426
427
}

bool cmState::GetLanguageEnabled(std::string const& l) const
{
  return std::binary_search(this->EnabledLanguages.begin(),
                            this->EnabledLanguages.end(), l);
}

std::vector<std::string> cmState::GetEnabledLanguages() const
{
  return this->EnabledLanguages;
}

428
429
430
431
432
void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
{
  this->EnabledLanguages = langs;
}

433
434
435
436
void cmState::ClearEnabledLanguages()
{
  this->EnabledLanguages.clear();
}
437
438
439
440
441
442
443
444
445
446

bool cmState::GetIsInTryCompile() const
{
  return this->IsInTryCompile;
}

void cmState::SetIsInTryCompile(bool b)
{
  this->IsInTryCompile = b;
}
447
448
449
450
451
452
453
454

void cmState::RenameCommand(std::string const& oldName,
                            std::string const& newName)
{
  // if the command already exists, free the old one
  std::string sOldName = cmSystemTools::LowerCase(oldName);
  std::string sNewName = cmSystemTools::LowerCase(newName);
  std::map<std::string, cmCommand*>::iterator pos =
455
456
    this->Commands.find(sOldName);
  if (pos == this->Commands.end()) {
457
    return;
458
  }
459
460
461
  cmCommand* cmd = pos->second;

  pos = this->Commands.find(sNewName);
462
  if (pos != this->Commands.end()) {
463
464
    delete pos->second;
    this->Commands.erase(pos);
465
  }
466
467
468
469
470
471
472
473
474
475
  this->Commands.insert(std::make_pair(sNewName, cmd));
  pos = this->Commands.find(sOldName);
  this->Commands.erase(pos);
}

void cmState::AddCommand(cmCommand* command)
{
  std::string name = cmSystemTools::LowerCase(command->GetName());
  // if the command already exists, free the old one
  std::map<std::string, cmCommand*>::iterator pos = this->Commands.find(name);
476
  if (pos != this->Commands.end()) {
477
478
    delete pos->second;
    this->Commands.erase(pos);
479
  }
480
481
482
483
484
485
  this->Commands.insert(std::make_pair(name, command));
}

void cmState::RemoveUnscriptableCommands()
{
  std::vector<std::string> unscriptableCommands;
486
487
488
489
  for (std::map<std::string, cmCommand*>::iterator pos =
         this->Commands.begin();
       pos != this->Commands.end();) {
    if (!pos->second->IsScriptable()) {
490
491
      delete pos->second;
      this->Commands.erase(pos++);
492
    } else {
493
494
      ++pos;
    }
495
  }
496
497
498
499
}

cmCommand* cmState::GetCommand(std::string const& name) const
{
Daniel Pfeifer's avatar
Daniel Pfeifer committed
500
  cmCommand* command = CM_NULLPTR;
501
502
  std::string sName = cmSystemTools::LowerCase(name);
  std::map<std::string, cmCommand*>::const_iterator pos =
503
504
    this->Commands.find(sName);
  if (pos != this->Commands.end()) {
505
    command = (*pos).second;
506
  }
507
508
509
510
511
512
513
  return command;
}

std::vector<std::string> cmState::GetCommandNames() const
{
  std::vector<std::string> commandNames;
  commandNames.reserve(this->Commands.size());
514
515
516
  std::map<std::string, cmCommand*>::const_iterator cmds =
    this->Commands.begin();
  for (; cmds != this->Commands.end(); ++cmds) {
517
    commandNames.push_back(cmds->first);
518
  }
519
520
521
522
523
  return commandNames;
}

void cmState::RemoveUserDefinedCommands()
{
524
  std::vector<cmCommand*> renamedCommands;
525
526
  for (std::map<std::string, cmCommand*>::iterator j = this->Commands.begin();
       j != this->Commands.end();) {
527
    if (j->second->IsA("cmMacroHelperCommand") ||
528
        j->second->IsA("cmFunctionHelperCommand")) {
529
530
      delete j->second;
      this->Commands.erase(j++);
531
    } else if (j->first != j->second->GetName()) {
532
533
      renamedCommands.push_back(j->second);
      this->Commands.erase(j++);
534
    } else {
535
536
      ++j;
    }
537
  }
538
  for (std::vector<cmCommand*>::const_iterator it = renamedCommands.begin();
539
       it != renamedCommands.end(); ++it) {
540
    this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
541
  }
542
}
543
544
545

void cmState::SetGlobalProperty(const std::string& prop, const char* value)
{
546
  this->GlobalProperties.SetProperty(prop, value);
547
548
}

549
550
void cmState::AppendGlobalProperty(const std::string& prop, const char* value,
                                   bool asString)
551
{
552
  this->GlobalProperties.AppendProperty(prop, value, asString);
553
554
}

555
const char* cmState::GetGlobalProperty(const std::string& prop)
556
{
557
  if (prop == "CACHE_VARIABLES") {
558
559
    std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
    this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
560
  } else if (prop == "COMMANDS") {
561
562
    std::vector<std::string> commands = this->GetCommandNames();
    this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
563
  } else if (prop == "IN_TRY_COMPILE") {
564
    this->SetGlobalProperty("IN_TRY_COMPILE",
565
566
                            this->IsInTryCompile ? "1" : "0");
  } else if (prop == "ENABLED_LANGUAGES") {
567
568
569
    std::string langs;
    langs = cmJoin(this->EnabledLanguages, ";");
    this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
570
  }
571
#define STRING_LIST_ELEMENT(F) ";" #F
572
  if (prop == "CMAKE_C_KNOWN_FEATURES") {
573
    return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
574
575
  }
  if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
576
    return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
577
  }
578
#undef STRING_LIST_ELEMENT
579
  return this->GlobalProperties.GetPropertyValue(prop);
580
581
582
583
584
585
}

bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
  return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
}
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603

void cmState::SetSourceDirectory(std::string const& sourceDirectory)
{
  this->SourceDirectory = sourceDirectory;
  cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
}

const char* cmState::GetSourceDirectory() const
{
  return this->SourceDirectory.c_str();
}

void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
{
  this->BinaryDirectory = binaryDirectory;
  cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
}

604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
void cmState::SetWindowsShell(bool windowsShell)
{
  this->WindowsShell = windowsShell;
}

bool cmState::UseWindowsShell() const
{
  return this->WindowsShell;
}

void cmState::SetWindowsVSIDE(bool windowsVSIDE)
{
  this->WindowsVSIDE = windowsVSIDE;
}

bool cmState::UseWindowsVSIDE() const
{
  return this->WindowsVSIDE;
}

void cmState::SetWatcomWMake(bool watcomWMake)
{
  this->WatcomWMake = watcomWMake;
}

bool cmState::UseWatcomWMake() const
{
  return this->WatcomWMake;
}

void cmState::SetMinGWMake(bool minGWMake)
{
  this->MinGWMake = minGWMake;
}

bool cmState::UseMinGWMake() const
{
  return this->MinGWMake;
}

void cmState::SetNMake(bool nMake)
{
  this->NMake = nMake;
}

bool cmState::UseNMake() const
{
  return this->NMake;
}

void cmState::SetMSYSShell(bool mSYSShell)
{
  this->MSYSShell = mSYSShell;
}

bool cmState::UseMSYSShell() const
{
  return this->MSYSShell;
}

664
665
unsigned int cmState::GetCacheMajorVersion() const
{
666
  return this->CacheManager->GetCacheMajorVersion();
667
668
669
670
}

unsigned int cmState::GetCacheMinorVersion() const
{
671
  return this->CacheManager->GetCacheMinorVersion();
672
673
}

674
675
676
677
const char* cmState::GetBinaryDirectory() const
{
  return this->BinaryDirectory.c_str();
}
Stephen Kelly's avatar
Stephen Kelly committed
678

679
void cmStateDirectory::ComputeRelativePathTopSource()
680
681
682
683
684
{
  // Relative path conversion inside the source tree is not used to
  // construct relative paths passed to build tools so it is safe to use
  // even when the source is a network path.

685
  cmState::Snapshot snapshot = this->Snapshot_;
686
687
  std::vector<cmState::Snapshot> snapshots;
  snapshots.push_back(snapshot);
688
  while (true) {
689
    snapshot = snapshot.GetBuildsystemDirectoryParent();
690
    if (snapshot.IsValid()) {
691
      snapshots.push_back(snapshot);
692
    } else {
693
694
      break;
    }
695
  }
696

697
  std::string result = snapshots.front().GetDirectory().GetCurrentSource();
698
699

  for (std::vector<cmState::Snapshot>::const_iterator it =
700
701
         snapshots.begin() + 1;
       it != snapshots.end(); ++it) {
702
    std::string currentSource = it->GetDirectory().GetCurrentSource();
703
    if (cmSystemTools::IsSubDirectory(result, currentSource)) {
704
705
      result = currentSource;
    }
706
  }
707
  this->DirectoryState->RelativePathTopSource = result;
708
709
}

710
void cmStateDirectory::ComputeRelativePathTopBinary()
711
{
712
  cmState::Snapshot snapshot = this->Snapshot_;
713
714
  std::vector<cmState::Snapshot> snapshots;
  snapshots.push_back(snapshot);
715
  while (true) {
716
    snapshot = snapshot.GetBuildsystemDirectoryParent();
717
    if (snapshot.IsValid()) {
718
      snapshots.push_back(snapshot);
719
    } else {
720
721
      break;
    }
722
  }
723

724
  std::string result = snapshots.front().GetDirectory().GetCurrentBinary();
725
726

  for (std::vector<cmState::Snapshot>::const_iterator it =
727
728
         snapshots.begin() + 1;
       it != snapshots.end(); ++it) {
729
    std::string currentBinary = it->GetDirectory().GetCurrentBinary();
730
    if (cmSystemTools::IsSubDirectory(result, currentBinary)) {
731
732
      result = currentBinary;
    }
733
  }
734
735
736
737

  // The current working directory on Windows cannot be a network
  // path.  Therefore relative paths cannot work when the binary tree
  // is a network path.
738
  if (result.size() < 2 || result.substr(0, 2) != "//") {
739
    this->DirectoryState->RelativePathTopBinary = result;
740
  } else {
741
    this->DirectoryState->RelativePathTopBinary = "";
742
  }
743
744
}

745
746
cmState::Snapshot cmState::CreateBaseSnapshot()
{
747
748
  cmStateDetail::PositionType pos =
    this->SnapshotData.Push(this->SnapshotData.Root());
749
  pos->DirectoryParent = this->SnapshotData.Root();
750
  pos->ScopeParent = this->SnapshotData.Root();
751
  pos->SnapshotType = cmStateEnums::BaseType;
752
  pos->Keep = true;
753
  pos->BuildSystemDirectory =
754
    this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
755
  pos->ExecutionListFile =
756
    this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
757
758
759
  pos->IncludeDirectoryPosition = 0;
  pos->CompileDefinitionsPosition = 0;
  pos->CompileOptionsPosition = 0;
760
  pos->BuildSystemDirectory->DirectoryEnd = pos;
761
762
763
764
765
  pos->Policies = this->PolicyStack.Root();
  pos->PolicyRoot = this->PolicyStack.Root();
  pos->PolicyScope = this->PolicyStack.Root();
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
766
  pos->Vars = this->VarTree.Push(this->VarTree.Root());
767
768
769
  assert(pos->Vars.IsValid());
  pos->Parent = this->VarTree.Root();
  pos->Root = this->VarTree.Root();
770
771
772
  return cmState::Snapshot(this, pos);
}

773
774
cmState::Snapshot cmState::CreateBuildsystemDirectorySnapshot(
  Snapshot originSnapshot)
Stephen Kelly's avatar
Stephen Kelly committed
775
{
776
  assert(originSnapshot.IsValid());
777
778
  cmStateDetail::PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position);
779
  pos->DirectoryParent = originSnapshot.Position;
780
  pos->ScopeParent = originSnapshot.Position;
781
  pos->SnapshotType = cmStateEnums::BuildsystemDirectoryType;
782
  pos->Keep = true;
783
784
  pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
    originSnapshot.Position->BuildSystemDirectory);
785
  pos->ExecutionListFile =
786
    this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
787
  pos->BuildSystemDirectory->DirectoryEnd = pos;
788
789
790
791
792
  pos->Policies = originSnapshot.Position->Policies;
  pos->PolicyRoot = originSnapshot.Position->Policies;
  pos->PolicyScope = originSnapshot.Position->Policies;
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
793

794
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
795
796
  pos->Parent = origin;
  pos->Root = origin;
797
  pos->Vars = this->VarTree.Push(origin);
798

799
800
  cmState::Snapshot snapshot = cmState::Snapshot(this, pos);
  originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
801
  snapshot.SetDefaultDefinitions();
802
  snapshot.InitializeFromParent();
803
  snapshot.SetDirectoryDefinitions();
804
  return snapshot;
Stephen Kelly's avatar
Stephen Kelly committed
805
806
}

807
808
cmState::Snapshot cmState::CreateFunctionCallSnapshot(
  cmState::Snapshot originSnapshot, std::string const& fileName)
809
{
810
  cmStateDetail::PositionType pos =
811
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
812
  pos->ScopeParent = originSnapshot.Position;
813
  pos->SnapshotType = cmStateEnums::FunctionCallType;
814
  pos->Keep = false;
815
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
816
    originSnapshot.Position->ExecutionListFile, fileName);
817
  pos->BuildSystemDirectory->DirectoryEnd = pos;
818
  pos->PolicyScope = originSnapshot.Position->Policies;
819
  assert(originSnapshot.Position->Vars.IsValid());
820
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
821
  pos->Parent = origin;
822
  pos->Vars = this->VarTree.Push(origin);
823
824
825
  return cmState::Snapshot(this, pos);
}

826
827
cmState::Snapshot cmState::CreateMacroCallSnapshot(
  cmState::Snapshot originSnapshot, std::string const& fileName)
828
{
829
  cmStateDetail::PositionType pos =
830
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
831
  pos->SnapshotType = cmStateEnums::MacroCallType;
832
  pos->Keep = false;
833
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
834
    originSnapshot.Position->ExecutionListFile, fileName);
835
  assert(originSnapshot.Position->Vars.IsValid());
836
  pos->BuildSystemDirectory->DirectoryEnd = pos;
837
  pos->PolicyScope = originSnapshot.Position->Policies;
838
839
840
  return cmState::Snapshot(this, pos);
}

841
842
cmState::Snapshot cmState::CreateIncludeFileSnapshot(
  cmState::Snapshot originSnapshot, const std::string& fileName)
843
{
844
  cmStateDetail::PositionType pos =
845
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
846
  pos->SnapshotType = cmStateEnums::IncludeFileType;
847
  pos->Keep = true;
848
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
849
    originSnapshot.Position->ExecutionListFile, fileName);
850
  assert(originSnapshot.Position->Vars.IsValid());
851
  pos->BuildSystemDirectory->DirectoryEnd = pos;
852
  pos->PolicyScope = originSnapshot.Position->Policies;
853
854
855
  return cmState::Snapshot(this, pos);
}

856
857
cmState::Snapshot cmState::CreateVariableScopeSnapshot(
  cmState::Snapshot originSnapshot)
858
{
859
  cmStateDetail::PositionType pos =
860
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
861
  pos->ScopeParent = originSnapshot.Position;
862
  pos->SnapshotType = cmStateEnums::VariableScopeType;
863
  pos->Keep = false;
864
  pos->PolicyScope = originSnapshot.Position->Policies;
865
  assert(originSnapshot.Position->Vars.IsValid());
866

867
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
868
  pos->Parent = origin;
869
  pos->Vars = this->VarTree.Push(origin);
870
  assert(pos->Vars.IsValid());
871
872
873
  return cmState::Snapshot(this, pos);
}

874
875
cmState::Snapshot cmState::CreateInlineListFileSnapshot(
  cmState::Snapshot originSnapshot, const std::string& fileName)
876
{
877
  cmStateDetail::PositionType pos =
878
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
879
  pos->SnapshotType = cmStateEnums::InlineListFileType;
880
  pos->Keep = true;
881
  pos->ExecutionListFile = this->ExecutionListFiles.Push(