1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
13 #include "cmsys/RegularExpression.hxx"
15 #include "cmCacheManager.h"
16 #include "cmCommand.h"
17 #include "cmDefinitions.h"
18 #include "cmExecutionStatus.h"
19 #include "cmGlobVerificationManager.h"
20 #include "cmListFileCache.h"
21 #include "cmMakefile.h"
22 #include "cmMessageType.h"
23 #include "cmStatePrivate.h"
24 #include "cmStateSnapshot.h"
25 #include "cmStringAlgorithms.h"
26 #include "cmSystemTools.h"
29 cmState::cmState(Mode mode, ProjectKind projectKind)
31 , StateProjectKind(projectKind)
33 this->CacheManager = cm::make_unique<cmCacheManager>();
34 this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>();
37 cmState::~cmState() = default;
39 const std::string& cmState::GetTargetTypeName(
40 cmStateEnums::TargetType targetType)
42 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
43 MAKE_STATIC_PROP(STATIC_LIBRARY);
44 MAKE_STATIC_PROP(MODULE_LIBRARY);
45 MAKE_STATIC_PROP(SHARED_LIBRARY);
46 MAKE_STATIC_PROP(OBJECT_LIBRARY);
47 MAKE_STATIC_PROP(EXECUTABLE);
48 MAKE_STATIC_PROP(UTILITY);
49 MAKE_STATIC_PROP(GLOBAL_TARGET);
50 MAKE_STATIC_PROP(INTERFACE_LIBRARY);
51 MAKE_STATIC_PROP(UNKNOWN_LIBRARY);
52 static const std::string propEmpty;
53 #undef MAKE_STATIC_PROP
56 case cmStateEnums::STATIC_LIBRARY:
57 return propSTATIC_LIBRARY;
58 case cmStateEnums::MODULE_LIBRARY:
59 return propMODULE_LIBRARY;
60 case cmStateEnums::SHARED_LIBRARY:
61 return propSHARED_LIBRARY;
62 case cmStateEnums::OBJECT_LIBRARY:
63 return propOBJECT_LIBRARY;
64 case cmStateEnums::EXECUTABLE:
65 return propEXECUTABLE;
66 case cmStateEnums::UTILITY:
68 case cmStateEnums::GLOBAL_TARGET:
69 return propGLOBAL_TARGET;
70 case cmStateEnums::INTERFACE_LIBRARY:
71 return propINTERFACE_LIBRARY;
72 case cmStateEnums::UNKNOWN_LIBRARY:
73 return propUNKNOWN_LIBRARY;
75 assert(false && "Unexpected target type");
79 static const std::array<std::string, 7> cmCacheEntryTypes = {
80 { "BOOL", "PATH", "FILEPATH", "STRING", "INTERNAL", "STATIC",
84 const std::string& cmState::CacheEntryTypeToString(
85 cmStateEnums::CacheEntryType type)
87 if (type < cmStateEnums::BOOL || type > cmStateEnums::UNINITIALIZED) {
88 type = cmStateEnums::UNINITIALIZED;
90 return cmCacheEntryTypes[type];
93 cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(
96 cmStateEnums::CacheEntryType type = cmStateEnums::STRING;
97 StringToCacheEntryType(s, type);
101 bool cmState::StringToCacheEntryType(const std::string& s,
102 cmStateEnums::CacheEntryType& type)
104 for (size_t i = 0; i < cmCacheEntryTypes.size(); ++i) {
105 if (s == cmCacheEntryTypes[i]) {
106 type = static_cast<cmStateEnums::CacheEntryType>(i);
113 bool cmState::IsCacheEntryType(std::string const& key)
116 cmCacheEntryTypes.begin(), cmCacheEntryTypes.end(),
117 [&key](std::string const& i) -> bool { return key == i; });
120 bool cmState::LoadCache(const std::string& path, bool internal,
121 std::set<std::string>& excludes,
122 std::set<std::string>& includes)
124 return this->CacheManager->LoadCache(path, internal, excludes, includes);
127 bool cmState::SaveCache(const std::string& path, cmMessenger* messenger)
129 return this->CacheManager->SaveCache(path, messenger);
132 bool cmState::DeleteCache(const std::string& path)
134 return this->CacheManager->DeleteCache(path);
137 bool cmState::IsCacheLoaded() const
139 return this->CacheManager->IsCacheLoaded();
142 std::vector<std::string> cmState::GetCacheEntryKeys() const
144 return this->CacheManager->GetCacheEntryKeys();
147 cmValue cmState::GetCacheEntryValue(std::string const& key) const
149 return this->CacheManager->GetCacheEntryValue(key);
152 std::string cmState::GetSafeCacheEntryValue(std::string const& key) const
154 if (cmValue val = this->GetCacheEntryValue(key)) {
157 return std::string();
160 cmValue cmState::GetInitializedCacheValue(std::string const& key) const
162 return this->CacheManager->GetInitializedCacheValue(key);
165 cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
166 std::string const& key) const
168 return this->CacheManager->GetCacheEntryType(key);
171 void cmState::SetCacheEntryValue(std::string const& key,
172 std::string const& value)
174 this->CacheManager->SetCacheEntryValue(key, value);
177 void cmState::SetCacheEntryProperty(std::string const& key,
178 std::string const& propertyName,
179 std::string const& value)
181 this->CacheManager->SetCacheEntryProperty(key, propertyName, value);
184 void cmState::SetCacheEntryBoolProperty(std::string const& key,
185 std::string const& propertyName,
188 this->CacheManager->SetCacheEntryBoolProperty(key, propertyName, value);
191 std::vector<std::string> cmState::GetCacheEntryPropertyList(
192 const std::string& key)
194 return this->CacheManager->GetCacheEntryPropertyList(key);
197 cmValue cmState::GetCacheEntryProperty(std::string const& key,
198 std::string const& propertyName)
200 return this->CacheManager->GetCacheEntryProperty(key, propertyName);
203 bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
204 std::string const& propertyName)
206 return this->CacheManager->GetCacheEntryPropertyAsBool(key, propertyName);
209 void cmState::AddCacheEntry(const std::string& key, cmValue value,
210 const char* helpString,
211 cmStateEnums::CacheEntryType type)
213 this->CacheManager->AddCacheEntry(key, value, helpString, type);
216 bool cmState::DoWriteGlobVerifyTarget() const
218 return this->GlobVerificationManager->DoWriteVerifyTarget();
221 std::string const& cmState::GetGlobVerifyScript() const
223 return this->GlobVerificationManager->GetVerifyScript();
226 std::string const& cmState::GetGlobVerifyStamp() const
228 return this->GlobVerificationManager->GetVerifyStamp();
231 bool cmState::SaveVerificationScript(const std::string& path,
232 cmMessenger* messenger)
234 return this->GlobVerificationManager->SaveVerificationScript(path,
238 void cmState::AddGlobCacheEntry(
239 bool recurse, bool listDirectories, bool followSymlinks,
240 const std::string& relative, const std::string& expression,
241 const std::vector<std::string>& files, const std::string& variable,
242 cmListFileBacktrace const& backtrace, cmMessenger* messenger)
244 this->GlobVerificationManager->AddCacheEntry(
245 recurse, listDirectories, followSymlinks, relative, expression, files,
246 variable, backtrace, messenger);
249 void cmState::RemoveCacheEntry(std::string const& key)
251 this->CacheManager->RemoveCacheEntry(key);
254 void cmState::AppendCacheEntryProperty(const std::string& key,
255 const std::string& property,
256 const std::string& value, bool asString)
258 this->CacheManager->AppendCacheEntryProperty(key, property, value, asString);
261 void cmState::RemoveCacheEntryProperty(std::string const& key,
262 std::string const& propertyName)
264 this->CacheManager->RemoveCacheEntryProperty(key, propertyName);
267 cmStateSnapshot cmState::Reset()
269 this->GlobalProperties.Clear();
270 this->PropertyDefinitions = {};
271 this->GlobVerificationManager->Reset();
273 cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
274 this->ExecutionListFiles.Truncate();
277 cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it =
278 this->BuildsystemDirectory.Truncate();
279 it->IncludeDirectories.clear();
280 it->CompileDefinitions.clear();
281 it->CompileOptions.clear();
282 it->LinkOptions.clear();
283 it->LinkDirectories.clear();
284 it->CurrentScope = pos;
285 it->NormalTargetNames.clear();
286 it->ImportedTargetNames.clear();
287 it->Properties.Clear();
288 it->Children.clear();
291 this->PolicyStack.Clear();
292 pos->Policies = this->PolicyStack.Root();
293 pos->PolicyRoot = this->PolicyStack.Root();
294 pos->PolicyScope = this->PolicyStack.Root();
295 assert(pos->Policies.IsValid());
296 assert(pos->PolicyRoot.IsValid());
300 *cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
302 *cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
303 this->VarTree.Clear();
304 pos->Vars = this->VarTree.Push(this->VarTree.Root());
305 pos->Parent = this->VarTree.Root();
306 pos->Root = this->VarTree.Root();
308 pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir);
309 pos->Vars->Set("CMAKE_BINARY_DIR", binDir);
312 this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
314 this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::DIRECTORY, "", "",
316 this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY, "", "",
319 this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::TARGET, "", "",
321 this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true);
322 this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true);
324 return { this, pos };
327 void cmState::DefineProperty(const std::string& name,
328 cmProperty::ScopeType scope,
329 const std::string& ShortDescription,
330 const std::string& FullDescription, bool chained,
331 const std::string& initializeFromVariable)
333 this->PropertyDefinitions.DefineProperty(name, scope, ShortDescription,
334 FullDescription, chained,
335 initializeFromVariable);
338 cmPropertyDefinition const* cmState::GetPropertyDefinition(
339 const std::string& name, cmProperty::ScopeType scope) const
341 return this->PropertyDefinitions.GetPropertyDefinition(name, scope);
344 bool cmState::IsPropertyChained(const std::string& name,
345 cmProperty::ScopeType scope) const
347 if (const auto* def = this->GetPropertyDefinition(name, scope)) {
348 return def->IsChained();
353 void cmState::SetLanguageEnabled(std::string const& l)
355 auto it = std::lower_bound(this->EnabledLanguages.begin(),
356 this->EnabledLanguages.end(), l);
357 if (it == this->EnabledLanguages.end() || *it != l) {
358 this->EnabledLanguages.insert(it, l);
362 bool cmState::GetLanguageEnabled(std::string const& l) const
364 return std::binary_search(this->EnabledLanguages.begin(),
365 this->EnabledLanguages.end(), l);
368 std::vector<std::string> cmState::GetEnabledLanguages() const
370 return this->EnabledLanguages;
373 void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
375 this->EnabledLanguages = langs;
378 void cmState::ClearEnabledLanguages()
380 this->EnabledLanguages.clear();
383 bool cmState::GetIsGeneratorMultiConfig() const
385 return this->IsGeneratorMultiConfig;
388 void cmState::SetIsGeneratorMultiConfig(bool b)
390 this->IsGeneratorMultiConfig = b;
393 void cmState::AddBuiltinCommand(std::string const& name,
394 std::unique_ptr<cmCommand> command)
396 this->AddBuiltinCommand(name, cmLegacyCommandWrapper(std::move(command)));
399 void cmState::AddBuiltinCommand(std::string const& name, Command command)
401 assert(name == cmSystemTools::LowerCase(name));
402 assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
403 this->BuiltinCommands.emplace(name, std::move(command));
406 static bool InvokeBuiltinCommand(cmState::BuiltinCommand command,
407 std::vector<cmListFileArgument> const& args,
408 cmExecutionStatus& status)
410 cmMakefile& mf = status.GetMakefile();
411 std::vector<std::string> expandedArguments;
412 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.
417 return command(expandedArguments, status);
420 void cmState::AddBuiltinCommand(std::string const& name,
421 BuiltinCommand command)
423 this->AddBuiltinCommand(
425 [command](const std::vector<cmListFileArgument>& args,
426 cmExecutionStatus& status) -> bool {
427 return InvokeBuiltinCommand(command, args, status);
431 void cmState::AddFlowControlCommand(std::string const& name, Command command)
433 this->FlowControlCommands.insert(name);
434 this->AddBuiltinCommand(name, std::move(command));
437 void cmState::AddFlowControlCommand(std::string const& name,
438 BuiltinCommand command)
440 this->FlowControlCommands.insert(name);
441 this->AddBuiltinCommand(name, command);
444 void cmState::AddDisallowedCommand(std::string const& name,
445 BuiltinCommand command,
446 cmPolicies::PolicyID policy,
449 this->AddBuiltinCommand(
451 [command, policy, message](const std::vector<cmListFileArgument>& args,
452 cmExecutionStatus& status) -> bool {
453 cmMakefile& mf = status.GetMakefile();
454 switch (mf.GetPolicyStatus(policy)) {
455 case cmPolicies::WARN:
456 mf.IssueMessage(MessageType::AUTHOR_WARNING,
457 cmPolicies::GetPolicyWarning(policy));
459 case cmPolicies::OLD:
461 case cmPolicies::REQUIRED_IF_USED:
462 case cmPolicies::REQUIRED_ALWAYS:
463 case cmPolicies::NEW:
464 mf.IssueMessage(MessageType::FATAL_ERROR, message);
467 return InvokeBuiltinCommand(command, args, status);
471 void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
473 this->AddBuiltinCommand(
475 [name, error](std::vector<cmListFileArgument> const&,
476 cmExecutionStatus& status) -> bool {
477 cmValue versionValue =
478 status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
479 if (name == "endif" &&
480 (!versionValue || atof(versionValue->c_str()) <= 1.4)) {
483 status.SetError(error);
488 void cmState::AddUnexpectedFlowControlCommand(std::string const& name,
491 this->FlowControlCommands.insert(name);
492 this->AddUnexpectedCommand(name, error);
495 bool cmState::AddScriptedCommand(std::string const& name, BT<Command> command,
498 std::string sName = cmSystemTools::LowerCase(name);
500 if (this->FlowControlCommands.count(sName)) {
501 mf.GetCMakeInstance()->IssueMessage(
502 MessageType::FATAL_ERROR,
503 cmStrCat("Built-in flow control command \"", sName,
504 "\" cannot be overridden."),
506 cmSystemTools::SetFatalErrorOccurred();
510 // if the command already exists, give a new name to the old command.
511 if (Command oldCmd = this->GetCommandByExactName(sName)) {
512 this->ScriptedCommands["_" + sName] = oldCmd;
515 this->ScriptedCommands[sName] = std::move(command.Value);
519 cmState::Command cmState::GetCommand(std::string const& name) const
521 return this->GetCommandByExactName(cmSystemTools::LowerCase(name));
524 cmState::Command cmState::GetCommandByExactName(std::string const& name) const
526 auto pos = this->ScriptedCommands.find(name);
527 if (pos != this->ScriptedCommands.end()) {
530 pos = this->BuiltinCommands.find(name);
531 if (pos != this->BuiltinCommands.end()) {
537 std::vector<std::string> cmState::GetCommandNames() const
539 std::vector<std::string> commandNames;
540 commandNames.reserve(this->BuiltinCommands.size() +
541 this->ScriptedCommands.size());
542 for (auto const& bc : this->BuiltinCommands) {
543 commandNames.push_back(bc.first);
545 for (auto const& sc : this->ScriptedCommands) {
546 commandNames.push_back(sc.first);
548 std::sort(commandNames.begin(), commandNames.end());
549 commandNames.erase(std::unique(commandNames.begin(), commandNames.end()),
554 void cmState::RemoveBuiltinCommand(std::string const& name)
556 assert(name == cmSystemTools::LowerCase(name));
557 this->BuiltinCommands.erase(name);
560 void cmState::RemoveUserDefinedCommands()
562 this->ScriptedCommands.clear();
565 void cmState::SetGlobalProperty(const std::string& prop, const char* value)
567 this->GlobalProperties.SetProperty(prop, value);
569 void cmState::SetGlobalProperty(const std::string& prop, cmValue value)
571 this->GlobalProperties.SetProperty(prop, value);
574 void cmState::AppendGlobalProperty(const std::string& prop,
575 const std::string& value, bool asString)
577 this->GlobalProperties.AppendProperty(prop, value, asString);
580 cmValue cmState::GetGlobalProperty(const std::string& prop)
582 if (prop == "CACHE_VARIABLES") {
583 std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
584 this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
585 } else if (prop == "COMMANDS") {
586 std::vector<std::string> commands = this->GetCommandNames();
587 this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
588 } else if (prop == "IN_TRY_COMPILE") {
589 this->SetGlobalProperty(
591 this->StateProjectKind == ProjectKind::TryCompile ? "1" : "0");
592 } else if (prop == "GENERATOR_IS_MULTI_CONFIG") {
593 this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
594 this->IsGeneratorMultiConfig ? "1" : "0");
595 } else if (prop == "ENABLED_LANGUAGES") {
597 langs = cmJoin(this->EnabledLanguages, ";");
598 this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
599 } else if (prop == "CMAKE_ROLE") {
600 std::string mode = this->GetModeString();
601 this->SetGlobalProperty("CMAKE_ROLE", mode.c_str());
603 #define STRING_LIST_ELEMENT(F) ";" #F
604 if (prop == "CMAKE_C_KNOWN_FEATURES") {
605 static const std::string s_out(
606 &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]);
607 return cmValue(s_out);
609 if (prop == "CMAKE_C90_KNOWN_FEATURES") {
610 static const std::string s_out(
611 &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]);
612 return cmValue(s_out);
614 if (prop == "CMAKE_C99_KNOWN_FEATURES") {
615 static const std::string s_out(
616 &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]);
617 return cmValue(s_out);
619 if (prop == "CMAKE_C11_KNOWN_FEATURES") {
620 static const std::string s_out(
621 &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]);
622 return cmValue(s_out);
624 if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
625 static const std::string s_out(
626 &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]);
627 return cmValue(s_out);
629 if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
630 static const std::string s_out(
631 &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]);
632 return cmValue(s_out);
634 if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
635 static const std::string s_out(
636 &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]);
637 return cmValue(s_out);
639 if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
640 static const std::string s_out(
641 &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]);
642 return cmValue(s_out);
644 if (prop == "CMAKE_CUDA_KNOWN_FEATURES") {
645 static const std::string s_out(
646 &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]);
647 return cmValue(s_out);
650 #undef STRING_LIST_ELEMENT
651 return this->GlobalProperties.GetPropertyValue(prop);
654 bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
656 return cmIsOn(this->GetGlobalProperty(prop));
659 void cmState::SetSourceDirectory(std::string const& sourceDirectory)
661 this->SourceDirectory = sourceDirectory;
662 cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
665 std::string const& cmState::GetSourceDirectory() const
667 return this->SourceDirectory;
670 void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
672 this->BinaryDirectory = binaryDirectory;
673 cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
676 void cmState::SetWindowsShell(bool windowsShell)
678 this->WindowsShell = windowsShell;
681 bool cmState::UseWindowsShell() const
683 return this->WindowsShell;
686 void cmState::SetWindowsVSIDE(bool windowsVSIDE)
688 this->WindowsVSIDE = windowsVSIDE;
691 bool cmState::UseWindowsVSIDE() const
693 return this->WindowsVSIDE;
696 void cmState::SetGhsMultiIDE(bool ghsMultiIDE)
698 this->GhsMultiIDE = ghsMultiIDE;
701 bool cmState::UseGhsMultiIDE() const
703 return this->GhsMultiIDE;
706 void cmState::SetWatcomWMake(bool watcomWMake)
708 this->WatcomWMake = watcomWMake;
711 bool cmState::UseWatcomWMake() const
713 return this->WatcomWMake;
716 void cmState::SetMinGWMake(bool minGWMake)
718 this->MinGWMake = minGWMake;
721 bool cmState::UseMinGWMake() const
723 return this->MinGWMake;
726 void cmState::SetNMake(bool nMake)
731 bool cmState::UseNMake() const
736 void cmState::SetMSYSShell(bool mSYSShell)
738 this->MSYSShell = mSYSShell;
741 bool cmState::UseMSYSShell() const
743 return this->MSYSShell;
746 void cmState::SetNinjaMulti(bool ninjaMulti)
748 this->NinjaMulti = ninjaMulti;
751 bool cmState::UseNinjaMulti() const
753 return this->NinjaMulti;
756 unsigned int cmState::GetCacheMajorVersion() const
758 return this->CacheManager->GetCacheMajorVersion();
761 unsigned int cmState::GetCacheMinorVersion() const
763 return this->CacheManager->GetCacheMinorVersion();
766 cmState::Mode cmState::GetMode() const
768 return this->StateMode;
771 std::string cmState::GetModeString() const
773 return ModeToString(this->StateMode);
776 std::string cmState::ModeToString(cmState::Mode mode)
784 return "FIND_PACKAGE";
795 cmState::ProjectKind cmState::GetProjectKind() const
797 return this->StateProjectKind;
800 std::string const& cmState::GetBinaryDirectory() const
802 return this->BinaryDirectory;
805 cmStateSnapshot cmState::CreateBaseSnapshot()
807 cmStateDetail::PositionType pos =
808 this->SnapshotData.Push(this->SnapshotData.Root());
809 pos->DirectoryParent = this->SnapshotData.Root();
810 pos->ScopeParent = this->SnapshotData.Root();
811 pos->SnapshotType = cmStateEnums::BaseType;
813 pos->BuildSystemDirectory =
814 this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
815 pos->ExecutionListFile =
816 this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
817 pos->IncludeDirectoryPosition = 0;
818 pos->CompileDefinitionsPosition = 0;
819 pos->CompileOptionsPosition = 0;
820 pos->LinkOptionsPosition = 0;
821 pos->LinkDirectoriesPosition = 0;
822 pos->BuildSystemDirectory->CurrentScope = pos;
823 pos->Policies = this->PolicyStack.Root();
824 pos->PolicyRoot = this->PolicyStack.Root();
825 pos->PolicyScope = this->PolicyStack.Root();
826 assert(pos->Policies.IsValid());
827 assert(pos->PolicyRoot.IsValid());
828 pos->Vars = this->VarTree.Push(this->VarTree.Root());
829 assert(pos->Vars.IsValid());
830 pos->Parent = this->VarTree.Root();
831 pos->Root = this->VarTree.Root();
832 return { this, pos };
835 cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot(
836 cmStateSnapshot const& originSnapshot)
838 assert(originSnapshot.IsValid());
839 cmStateDetail::PositionType pos =
840 this->SnapshotData.Push(originSnapshot.Position);
841 pos->DirectoryParent = originSnapshot.Position;
842 pos->ScopeParent = originSnapshot.Position;
843 pos->SnapshotType = cmStateEnums::BuildsystemDirectoryType;
845 pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
846 originSnapshot.Position->BuildSystemDirectory);
847 pos->ExecutionListFile =
848 this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
849 pos->BuildSystemDirectory->CurrentScope = pos;
850 pos->Policies = originSnapshot.Position->Policies;
851 pos->PolicyRoot = originSnapshot.Position->Policies;
852 pos->PolicyScope = originSnapshot.Position->Policies;
853 assert(pos->Policies.IsValid());
854 assert(pos->PolicyRoot.IsValid());
856 cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
857 pos->Parent = origin;
859 pos->Vars = this->VarTree.Push(origin);
861 cmStateSnapshot snapshot = cmStateSnapshot(this, pos);
862 originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
863 snapshot.SetDefaultDefinitions();
864 snapshot.InitializeFromParent();
865 snapshot.SetDirectoryDefinitions();
869 cmStateSnapshot cmState::CreateDeferCallSnapshot(
870 cmStateSnapshot const& originSnapshot, std::string const& fileName)
872 cmStateDetail::PositionType pos =
873 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
874 pos->SnapshotType = cmStateEnums::DeferCallType;
876 pos->ExecutionListFile = this->ExecutionListFiles.Push(
877 originSnapshot.Position->ExecutionListFile, fileName);
878 assert(originSnapshot.Position->Vars.IsValid());
879 pos->BuildSystemDirectory->CurrentScope = pos;
880 pos->PolicyScope = originSnapshot.Position->Policies;
881 return { this, pos };
884 cmStateSnapshot cmState::CreateFunctionCallSnapshot(
885 cmStateSnapshot const& originSnapshot, std::string const& fileName)
887 cmStateDetail::PositionType pos =
888 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
889 pos->ScopeParent = originSnapshot.Position;
890 pos->SnapshotType = cmStateEnums::FunctionCallType;
892 pos->ExecutionListFile = this->ExecutionListFiles.Push(
893 originSnapshot.Position->ExecutionListFile, fileName);
894 pos->BuildSystemDirectory->CurrentScope = pos;
895 pos->PolicyScope = originSnapshot.Position->Policies;
896 assert(originSnapshot.Position->Vars.IsValid());
897 cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
898 pos->Parent = origin;
899 pos->Vars = this->VarTree.Push(origin);
900 return { this, pos };
903 cmStateSnapshot cmState::CreateMacroCallSnapshot(
904 cmStateSnapshot const& originSnapshot, std::string const& fileName)
906 cmStateDetail::PositionType pos =
907 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
908 pos->SnapshotType = cmStateEnums::MacroCallType;
910 pos->ExecutionListFile = this->ExecutionListFiles.Push(
911 originSnapshot.Position->ExecutionListFile, fileName);
912 assert(originSnapshot.Position->Vars.IsValid());
913 pos->BuildSystemDirectory->CurrentScope = pos;
914 pos->PolicyScope = originSnapshot.Position->Policies;
915 return { this, pos };
918 cmStateSnapshot cmState::CreateIncludeFileSnapshot(
919 cmStateSnapshot const& originSnapshot, std::string const& fileName)
921 cmStateDetail::PositionType pos =
922 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
923 pos->SnapshotType = cmStateEnums::IncludeFileType;
925 pos->ExecutionListFile = this->ExecutionListFiles.Push(
926 originSnapshot.Position->ExecutionListFile, fileName);
927 assert(originSnapshot.Position->Vars.IsValid());
928 pos->BuildSystemDirectory->CurrentScope = pos;
929 pos->PolicyScope = originSnapshot.Position->Policies;
930 return { this, pos };
933 cmStateSnapshot cmState::CreateVariableScopeSnapshot(
934 cmStateSnapshot const& originSnapshot)
936 cmStateDetail::PositionType pos =
937 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
938 pos->ScopeParent = originSnapshot.Position;
939 pos->SnapshotType = cmStateEnums::VariableScopeType;
941 pos->BuildSystemDirectory->CurrentScope = pos;
942 pos->PolicyScope = originSnapshot.Position->Policies;
943 assert(originSnapshot.Position->Vars.IsValid());
945 cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
946 pos->Parent = origin;
947 pos->Vars = this->VarTree.Push(origin);
948 assert(pos->Vars.IsValid());
949 return { this, pos };
952 cmStateSnapshot cmState::CreateInlineListFileSnapshot(
953 cmStateSnapshot const& originSnapshot, std::string const& fileName)
955 cmStateDetail::PositionType pos =
956 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
957 pos->SnapshotType = cmStateEnums::InlineListFileType;
959 pos->ExecutionListFile = this->ExecutionListFiles.Push(
960 originSnapshot.Position->ExecutionListFile, fileName);
961 pos->BuildSystemDirectory->CurrentScope = pos;
962 pos->PolicyScope = originSnapshot.Position->Policies;
963 return { this, pos };
966 cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
967 cmStateSnapshot const& originSnapshot)
969 cmStateDetail::PositionType pos =
970 this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
971 pos->SnapshotType = cmStateEnums::PolicyScopeType;
973 pos->BuildSystemDirectory->CurrentScope = pos;
974 pos->PolicyScope = originSnapshot.Position->Policies;
975 return { this, pos };
978 cmStateSnapshot cmState::Pop(cmStateSnapshot const& originSnapshot)
980 cmStateDetail::PositionType pos = originSnapshot.Position;
981 cmStateDetail::PositionType prevPos = pos;
983 prevPos->IncludeDirectoryPosition =
984 prevPos->BuildSystemDirectory->IncludeDirectories.size();
985 prevPos->CompileDefinitionsPosition =
986 prevPos->BuildSystemDirectory->CompileDefinitions.size();
987 prevPos->CompileOptionsPosition =
988 prevPos->BuildSystemDirectory->CompileOptions.size();
989 prevPos->LinkOptionsPosition =
990 prevPos->BuildSystemDirectory->LinkOptions.size();
991 prevPos->LinkDirectoriesPosition =
992 prevPos->BuildSystemDirectory->LinkDirectories.size();
993 prevPos->BuildSystemDirectory->CurrentScope = prevPos;
995 if (!pos->Keep && this->SnapshotData.IsLast(pos)) {
996 if (pos->Vars != prevPos->Vars) {
997 assert(this->VarTree.IsLast(pos->Vars));
998 this->VarTree.Pop(pos->Vars);
1000 if (pos->ExecutionListFile != prevPos->ExecutionListFile) {
1001 assert(this->ExecutionListFiles.IsLast(pos->ExecutionListFile));
1002 this->ExecutionListFiles.Pop(pos->ExecutionListFile);
1004 this->SnapshotData.Pop(pos);
1007 return { this, prevPos };
1010 static bool ParseEntryWithoutType(const std::string& entry, std::string& var,
1013 // input line is: key=value
1014 static cmsys::RegularExpression reg(
1015 "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1016 // input line is: "key"=value
1017 static cmsys::RegularExpression regQuoted(
1018 "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1020 if (regQuoted.find(entry)) {
1021 var = regQuoted.match(1);
1022 value = regQuoted.match(2);
1024 } else if (reg.find(entry)) {
1026 value = reg.match(2);
1030 // if value is enclosed in single quotes ('foo') then remove them
1031 // it is used to enclose trailing space or tab
1032 if (flag && value.size() >= 2 && value.front() == '\'' &&
1033 value.back() == '\'') {
1034 value = value.substr(1, value.size() - 2);
1040 bool cmState::ParseCacheEntry(const std::string& entry, std::string& var,
1042 cmStateEnums::CacheEntryType& type)
1044 // input line is: key:type=value
1045 static cmsys::RegularExpression reg(
1046 "^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1047 // input line is: "key":type=value
1048 static cmsys::RegularExpression regQuoted(
1049 "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
1051 if (regQuoted.find(entry)) {
1052 var = regQuoted.match(1);
1053 type = cmState::StringToCacheEntryType(regQuoted.match(2));
1054 value = regQuoted.match(3);
1056 } else if (reg.find(entry)) {
1058 type = cmState::StringToCacheEntryType(reg.match(2));
1059 value = reg.match(3);
1063 // if value is enclosed in single quotes ('foo') then remove them
1064 // it is used to enclose trailing space or tab
1065 if (flag && value.size() >= 2 && value.front() == '\'' &&
1066 value.back() == '\'') {
1067 value = value.substr(1, value.size() - 2);
1071 return ParseEntryWithoutType(entry, var, value);
1077 cmState::Command cmState::GetDependencyProviderCommand(
1078 cmDependencyProvider::Method method) const
1080 return (this->DependencyProvider &&
1081 this->DependencyProvider->SupportsMethod(method))
1082 ? this->GetCommand(this->DependencyProvider->GetCommand())