cmState.cxx 56.3 KB
Newer Older
Stephen Kelly's avatar
Stephen Kelly committed
1
2
3
4
5
6
7
8
9
10
11
12
13
/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2015 Stephen Kelly <steveire@gmail.com>

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmState.h"

14
#include "cmAlgorithms.h"
15
#include "cmCacheManager.h"
16
#include "cmCommand.h"
17
#include "cmDefinitions.h"
18
19
20
#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmTypeMacro.h"
21
22
#include "cmVersion.h"
#include "cmake.h"
23

24
#include <algorithm>
25
#include <assert.h>
26
27
28
29
30
#include <cmsys/RegularExpression.hxx>
#include <iterator>
#include <stdio.h>
#include <string.h>
#include <utility>
Stephen Kelly's avatar
Stephen Kelly committed
31

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

52
struct cmState::PolicyStackEntry : public cmPolicies::PolicyMap
53
54
{
  typedef cmPolicies::PolicyMap derived;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  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)
  {
  }
70
71
72
  bool Weak;
};

73
74
struct cmState::BuildsystemDirectoryStateType
{
75
76
  cmState::PositionType DirectoryEnd;

77
78
79
80
81
82
83
84
85
86
87
88
  std::string Location;
  std::string OutputLocation;

  std::vector<std::string> CurrentSourceDirectoryComponents;
  std::vector<std::string> CurrentBinaryDirectoryComponents;
  // 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;
89
90
91
92
93
94
95
96
97

  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;
98

99
100
  std::string ProjectName;

101
  cmPropertyMap Properties;
102
103

  std::vector<cmState::Snapshot> Children;
104
105
};

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

118
119
cmState::~cmState()
{
120
  delete this->CacheManager;
121
122
123
  cmDeleteAll(this->Commands);
}

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

150
151
const char* cmCacheEntryTypes[] = { "BOOL",          "PATH",     "FILEPATH",
                                    "STRING",        "INTERNAL", "STATIC",
Daniel Pfeifer's avatar
Daniel Pfeifer committed
152
                                    "UNINITIALIZED", CM_NULLPTR };
153

154
const char* cmState::CacheEntryTypeToString(cmState::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
155
{
156
  if (type > 6) {
157
    return cmCacheEntryTypes[6];
158
  }
159
  return cmCacheEntryTypes[type];
Stephen Kelly's avatar
Stephen Kelly committed
160
161
}

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

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

184
185
186
187
bool cmState::LoadCache(const std::string& path, bool internal,
                        std::set<std::string>& excludes,
                        std::set<std::string>& includes)
{
188
  return this->CacheManager->LoadCache(path, internal, excludes, includes);
189
190
191
192
}

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

bool cmState::DeleteCache(const std::string& path)
{
198
  return this->CacheManager->DeleteCache(path);
199
200
}

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

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

221
const char* cmState::GetInitializedCacheValue(std::string const& key) const
Stephen Kelly's avatar
Stephen Kelly committed
222
{
223
  return this->CacheManager->GetInitializedCacheValue(key);
Stephen Kelly's avatar
Stephen Kelly committed
224
225
}

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

void cmState::SetCacheEntryValue(std::string const& key,
235
                                 std::string const& value)
Stephen Kelly's avatar
Stephen Kelly committed
236
{
237
  this->CacheManager->SetCacheEntryValue(key, value);
Stephen Kelly's avatar
Stephen Kelly committed
238
239
240
}

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

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

258
259
260
261
262
263
264
265
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
266
const char* cmState::GetCacheEntryProperty(std::string const& key,
267
                                           std::string const& propertyName)
Stephen Kelly's avatar
Stephen Kelly committed
268
{
269
270
271
  cmCacheManager::CacheIterator it =
    this->CacheManager->GetCacheIterator(key.c_str());
  if (!it.PropertyExists(propertyName)) {
Daniel Pfeifer's avatar
Daniel Pfeifer committed
272
    return CM_NULLPTR;
273
  }
Stephen Kelly's avatar
Stephen Kelly committed
274
275
276
277
  return it.GetProperty(propertyName);
}

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

void cmState::AddCacheEntry(const std::string& key, const char* value,
285
286
                            const char* helpString,
                            cmState::CacheEntryType type)
Stephen Kelly's avatar
Stephen Kelly committed
287
{
288
  this->CacheManager->AddCacheEntry(key, value, helpString, type);
Stephen Kelly's avatar
Stephen Kelly committed
289
290
291
292
}

void cmState::RemoveCacheEntry(std::string const& key)
{
293
  this->CacheManager->RemoveCacheEntry(key);
Stephen Kelly's avatar
Stephen Kelly committed
294
295
296
}

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

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

311
cmState::Snapshot cmState::Reset()
312
{
313
  this->GlobalProperties.clear();
314
  this->PropertyDefinitions.clear();
315

316
317
318
  PositionType pos = this->SnapshotData.Truncate();
  this->ExecutionListFiles.Truncate();

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

333
334
335
336
337
338
  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());
339
340

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

350
351
    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
    pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
352
353
  }

354
355
356
357
358
359
360
361
362
363
364
  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);
365
366

  return Snapshot(this, pos);
367
368
369
}

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

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

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

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

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

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;
}

431
432
433
434
435
void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
{
  this->EnabledLanguages = langs;
}

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

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

void cmState::SetIsInTryCompile(bool b)
{
  this->IsInTryCompile = b;
}
450
451
452
453
454
455
456
457

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 =
458
459
    this->Commands.find(sOldName);
  if (pos == this->Commands.end()) {
460
    return;
461
  }
462
463
464
  cmCommand* cmd = pos->second;

  pos = this->Commands.find(sNewName);
465
  if (pos != this->Commands.end()) {
466
467
    delete pos->second;
    this->Commands.erase(pos);
468
  }
469
470
471
472
473
474
475
476
477
478
  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);
479
  if (pos != this->Commands.end()) {
480
481
    delete pos->second;
    this->Commands.erase(pos);
482
  }
483
484
485
486
487
488
  this->Commands.insert(std::make_pair(name, command));
}

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

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

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

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

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

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

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

bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
  return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
}
589
590
591
592
593

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

  cmSystemTools::SplitPath(
596
597
    cmSystemTools::CollapseFullPath(this->SourceDirectory),
    this->SourceDirectoryComponents);
598
599
600
601
602
603
604
}

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

605
606
607
608
609
std::vector<std::string> const& cmState::GetSourceDirectoryComponents() const
{
  return this->SourceDirectoryComponents;
}

610
611
612
613
void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
{
  this->BinaryDirectory = binaryDirectory;
  cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
614
615

  cmSystemTools::SplitPath(
616
617
    cmSystemTools::CollapseFullPath(this->BinaryDirectory),
    this->BinaryDirectoryComponents);
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
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
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;
}

680
681
unsigned int cmState::GetCacheMajorVersion() const
{
682
  return this->CacheManager->GetCacheMajorVersion();
683
684
685
686
}

unsigned int cmState::GetCacheMinorVersion() const
{
687
  return this->CacheManager->GetCacheMinorVersion();
688
689
}

690
691
692
693
const char* cmState::GetBinaryDirectory() const
{
  return this->BinaryDirectory.c_str();
}
Stephen Kelly's avatar
Stephen Kelly committed
694

695
696
697
698
699
std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
{
  return this->BinaryDirectoryComponents;
}

700
void cmState::Directory::ComputeRelativePathTopSource()
701
702
703
704
705
{
  // 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.

706
  cmState::Snapshot snapshot = this->Snapshot_;
707
708
  std::vector<cmState::Snapshot> snapshots;
  snapshots.push_back(snapshot);
709
  while (true) {
710
    snapshot = snapshot.GetBuildsystemDirectoryParent();
711
    if (snapshot.IsValid()) {
712
      snapshots.push_back(snapshot);
713
    } else {
714
715
      break;
    }
716
  }
717

718
  std::string result = snapshots.front().GetDirectory().GetCurrentSource();
719
720

  for (std::vector<cmState::Snapshot>::const_iterator it =
721
722
         snapshots.begin() + 1;
       it != snapshots.end(); ++it) {
723
    std::string currentSource = it->GetDirectory().GetCurrentSource();
724
    if (cmSystemTools::IsSubDirectory(result, currentSource)) {
725
726
      result = currentSource;
    }
727
  }
728
  this->DirectoryState->RelativePathTopSource = result;
729
730
}

731
void cmState::Directory::ComputeRelativePathTopBinary()
732
{
733
  cmState::Snapshot snapshot = this->Snapshot_;
734
735
  std::vector<cmState::Snapshot> snapshots;
  snapshots.push_back(snapshot);
736
  while (true) {
737
    snapshot = snapshot.GetBuildsystemDirectoryParent();
738
    if (snapshot.IsValid()) {
739
      snapshots.push_back(snapshot);
740
    } else {
741
742
      break;
    }
743
  }
744

745
  std::string result = snapshots.front().GetDirectory().GetCurrentBinary();
746
747

  for (std::vector<cmState::Snapshot>::const_iterator it =
748
749
         snapshots.begin() + 1;
       it != snapshots.end(); ++it) {
750
    std::string currentBinary = it->GetDirectory().GetCurrentBinary();
751
    if (cmSystemTools::IsSubDirectory(result, currentBinary)) {
752
753
      result = currentBinary;
    }
754
  }
755
756
757
758

  // The current working directory on Windows cannot be a network
  // path.  Therefore relative paths cannot work when the binary tree
  // is a network path.
759
  if (result.size() < 2 || result.substr(0, 2) != "//") {
760
    this->DirectoryState->RelativePathTopBinary = result;
761
  } else {
762
    this->DirectoryState->RelativePathTopBinary = "";
763
  }
764
765
}

766
767
cmState::Snapshot cmState::CreateBaseSnapshot()
{
768
  PositionType pos = this->SnapshotData.Push(this->SnapshotData.Root());
769
  pos->DirectoryParent = this->SnapshotData.Root();
770
  pos->ScopeParent = this->SnapshotData.Root();
771
  pos->SnapshotType = BaseType;
772
  pos->Keep = true;
773
  pos->BuildSystemDirectory =
774
    this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
775
  pos->ExecutionListFile =
776
    this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
777
778
779
  pos->IncludeDirectoryPosition = 0;
  pos->CompileDefinitionsPosition = 0;
  pos->CompileOptionsPosition = 0;
780
  pos->BuildSystemDirectory->DirectoryEnd = pos;
781
782
783
784
785
  pos->Policies = this->PolicyStack.Root();
  pos->PolicyRoot = this->PolicyStack.Root();
  pos->PolicyScope = this->PolicyStack.Root();
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
786
  pos->Vars = this->VarTree.Push(this->VarTree.Root());
787
788
789
  assert(pos->Vars.IsValid());
  pos->Parent = this->VarTree.Root();
  pos->Root = this->VarTree.Root();
790
791
792
  return cmState::Snapshot(this, pos);
}

793
794
cmState::Snapshot cmState::CreateBuildsystemDirectorySnapshot(
  Snapshot originSnapshot)
Stephen Kelly's avatar
Stephen Kelly committed
795
{
796
  assert(originSnapshot.IsValid());
797
  PositionType pos = this->SnapshotData.Push(originSnapshot.Position);
798
  pos->DirectoryParent = originSnapshot.Position;
799
  pos->ScopeParent = originSnapshot.Position;
800
  pos->SnapshotType = BuildsystemDirectoryType;
801
  pos->Keep = true;
802
803
  pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
    originSnapshot.Position->BuildSystemDirectory);
804
  pos->ExecutionListFile =
805
    this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
806
  pos->BuildSystemDirectory->DirectoryEnd = pos;
807
808
809
810
811
  pos->Policies = originSnapshot.Position->Policies;
  pos->PolicyRoot = originSnapshot.Position->Policies;
  pos->PolicyScope = originSnapshot.Position->Policies;
  assert(pos->Policies.IsValid());
  assert(pos->PolicyRoot.IsValid());
812

813
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
814
815
  pos->Parent = origin;
  pos->Root = origin;
816
  pos->Vars = this->VarTree.Push(origin);
817

818
819
  cmState::Snapshot snapshot = cmState::Snapshot(this, pos);
  originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
820
  snapshot.SetDefaultDefinitions();
821
  snapshot.InitializeFromParent();
822
  snapshot.SetDirectoryDefinitions();
823
  return snapshot;
Stephen Kelly's avatar
Stephen Kelly committed
824
825
}

826
827
cmState::Snapshot cmState::CreateFunctionCallSnapshot(
  cmState::Snapshot originSnapshot, std::string const& fileName)
828
{
829
830
  PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
831
  pos->ScopeParent = originSnapshot.Position;
832
  pos->SnapshotType = FunctionCallType;
833
  pos->Keep = false;
834
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
835
    originSnapshot.Position->ExecutionListFile, fileName);
836
  pos->BuildSystemDirectory->DirectoryEnd = pos;
837
  pos->PolicyScope = originSnapshot.Position->Policies;
838
  assert(originSnapshot.Position->Vars.IsValid());
839
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
840
  pos->Parent = origin;
841
  pos->Vars = this->VarTree.Push(origin);
842
843
844
  return cmState::Snapshot(this, pos);
}

845
846
cmState::Snapshot cmState::CreateMacroCallSnapshot(
  cmState::Snapshot originSnapshot, std::string const& fileName)
847
{
848
849
  PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
850
  pos->SnapshotType = MacroCallType;
851
  pos->Keep = false;
852
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
853
    originSnapshot.Position->ExecutionListFile, fileName);
854
  assert(originSnapshot.Position->Vars.IsValid());
855
  pos->BuildSystemDirectory->DirectoryEnd = pos;
856
  pos->PolicyScope = originSnapshot.Position->Policies;
857
858
859
  return cmState::Snapshot(this, pos);
}

860
861
cmState::Snapshot cmState::CreateIncludeFileSnapshot(
  cmState::Snapshot originSnapshot, const std::string& fileName)
862
{
863
864
  PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
865
  pos->SnapshotType = IncludeFileType;
866
  pos->Keep = true;
867
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
868
    originSnapshot.Position->ExecutionListFile, fileName);
869
  assert(originSnapshot.Position->Vars.IsValid());
870
  pos->BuildSystemDirectory->DirectoryEnd = pos;
871
  pos->PolicyScope = originSnapshot.Position->Policies;
872
873
874
  return cmState::Snapshot(this, pos);
}

875
876
cmState::Snapshot cmState::CreateVariableScopeSnapshot(
  cmState::Snapshot originSnapshot)
877
{
878
879
  PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
880
881
  pos->ScopeParent = originSnapshot.Position;
  pos->SnapshotType = VariableScopeType;
882
  pos->Keep = false;
883
  pos->PolicyScope = originSnapshot.Position->Policies;
884
  assert(originSnapshot.Position->Vars.IsValid());
885

886
  cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
887
  pos->Parent = origin;
888
  pos->Vars = this->VarTree.Push(origin);
889
  assert(pos->Vars.IsValid());
890
891
892
  return cmState::Snapshot(this, pos);
}

893
894
cmState::Snapshot cmState::CreateInlineListFileSnapshot(
  cmState::Snapshot originSnapshot, const std::string& fileName)
895
{
896
897
  PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
898
  pos->SnapshotType = InlineListFileType;
899
  pos->Keep = true;
900
  pos->ExecutionListFile = this->ExecutionListFiles.Push(
901
    originSnapshot.Position->ExecutionListFile, fileName);
902
  pos->BuildSystemDirectory->DirectoryEnd = pos;
903
  pos->PolicyScope = originSnapshot.Position->Policies;
904
905
906
  return cmState::Snapshot(this, pos);
}

907
908
cmState::Snapshot cmState::CreatePolicyScopeSnapshot(
  cmState::Snapshot originSnapshot)
909
{
910
911
  PositionType pos =
    this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
912
  pos->SnapshotType = PolicyScopeType;
913
  pos->Keep = false;
914
  pos->BuildSystemDirectory->DirectoryEnd = pos;
915
  pos->PolicyScope = originSnapshot.Position->Policies;
916
917
918
  return cmState::Snapshot(this, pos);
}

919
920
921
922
923
cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
{
  PositionType pos = originSnapshot.Position;
  PositionType prevPos = pos;
  ++prevPos;
924
  prevPos->IncludeDirectoryPosition =
925
    prevPos->BuildSystemDirectory->IncludeDirectories.size();
926
  prevPos->CompileDefinitionsPosition =
927
    prevPos->BuildSystemDirectory->CompileDefinitions.size();
928
  prevPos->CompileOptionsPosition =
929
    prevPos->BuildSystemDirectory->CompileOptions.size();