1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
4 #include "cmStateDirectory.h"
10 #include <cm/iterator>
11 #include <cm/string_view>
12 #include <cmext/algorithm>
13 #include <cmext/string_view>
15 #include "cmAlgorithms.h"
16 #include "cmListFileCache.h"
17 #include "cmProperty.h"
18 #include "cmPropertyMap.h"
21 #include "cmStatePrivate.h"
22 #include "cmStateTypes.h"
23 #include "cmStringAlgorithms.h"
24 #include "cmSystemTools.h"
27 static std::string const kBINARY_DIR = "BINARY_DIR";
28 static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS";
29 static std::string const kSOURCE_DIR = "SOURCE_DIR";
30 static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES";
32 std::string const& cmStateDirectory::GetCurrentSource() const
34 return this->DirectoryState->Location;
37 void cmStateDirectory::SetCurrentSource(std::string const& dir)
39 std::string& loc = this->DirectoryState->Location;
41 cmSystemTools::ConvertToUnixSlashes(loc);
42 loc = cmSystemTools::CollapseFullPath(loc);
43 this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
46 std::string const& cmStateDirectory::GetCurrentBinary() const
48 return this->DirectoryState->OutputLocation;
51 void cmStateDirectory::SetCurrentBinary(std::string const& dir)
53 std::string& loc = this->DirectoryState->OutputLocation;
55 cmSystemTools::ConvertToUnixSlashes(loc);
56 loc = cmSystemTools::CollapseFullPath(loc);
57 this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
60 cmStateDirectory::cmStateDirectory(
61 cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter,
62 const cmStateSnapshot& snapshot)
63 : DirectoryState(iter)
68 template <typename T, typename U>
69 cmBTStringRange GetPropertyContent(T const& content, U contentEndPosition)
71 auto end = content.begin() + contentEndPosition;
73 auto rbegin = cm::make_reverse_iterator(end);
74 rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
76 return cmMakeRange(rbegin.base(), end);
79 template <typename T, typename U>
80 void AppendEntry(T& content, U& endContentPosition,
81 const BT<std::string>& value)
83 if (value.Value.empty()) {
87 assert(endContentPosition == content.size());
89 content.push_back(value);
91 endContentPosition = content.size();
94 template <typename T, typename U>
95 void SetContent(T& content, U& endContentPosition, const BT<std::string>& vec)
97 assert(endContentPosition == content.size());
99 content.resize(content.size() + 2);
101 content.back() = vec;
103 endContentPosition = content.size();
106 template <typename T, typename U>
107 void ClearContent(T& content, U& endContentPosition)
109 assert(endContentPosition == content.size());
111 content.resize(content.size() + 1);
113 endContentPosition = content.size();
116 cmBTStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const
118 return GetPropertyContent(
119 this->DirectoryState->IncludeDirectories,
120 this->Snapshot_.Position->IncludeDirectoryPosition);
123 void cmStateDirectory::AppendIncludeDirectoriesEntry(
124 const BT<std::string>& vec)
126 AppendEntry(this->DirectoryState->IncludeDirectories,
127 this->Snapshot_.Position->IncludeDirectoryPosition, vec);
130 void cmStateDirectory::PrependIncludeDirectoriesEntry(
131 const BT<std::string>& vec)
133 auto entryEnd = this->DirectoryState->IncludeDirectories.begin() +
134 this->Snapshot_.Position->IncludeDirectoryPosition;
136 auto rend = this->DirectoryState->IncludeDirectories.rend();
137 auto rbegin = cm::make_reverse_iterator(entryEnd);
138 rbegin = std::find(rbegin, rend, cmPropertySentinal);
140 auto entryIt = rbegin.base();
142 this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
144 this->Snapshot_.Position->IncludeDirectoryPosition =
145 this->DirectoryState->IncludeDirectories.size();
148 void cmStateDirectory::SetIncludeDirectories(const BT<std::string>& vec)
150 SetContent(this->DirectoryState->IncludeDirectories,
151 this->Snapshot_.Position->IncludeDirectoryPosition, vec);
154 void cmStateDirectory::ClearIncludeDirectories()
156 ClearContent(this->DirectoryState->IncludeDirectories,
157 this->Snapshot_.Position->IncludeDirectoryPosition);
160 cmBTStringRange cmStateDirectory::GetCompileDefinitionsEntries() const
162 return GetPropertyContent(
163 this->DirectoryState->CompileDefinitions,
164 this->Snapshot_.Position->CompileDefinitionsPosition);
167 void cmStateDirectory::AppendCompileDefinitionsEntry(
168 const BT<std::string>& vec)
170 AppendEntry(this->DirectoryState->CompileDefinitions,
171 this->Snapshot_.Position->CompileDefinitionsPosition, vec);
174 void cmStateDirectory::SetCompileDefinitions(const BT<std::string>& vec)
176 SetContent(this->DirectoryState->CompileDefinitions,
177 this->Snapshot_.Position->CompileDefinitionsPosition, vec);
180 void cmStateDirectory::ClearCompileDefinitions()
182 ClearContent(this->DirectoryState->CompileDefinitions,
183 this->Snapshot_.Position->CompileDefinitionsPosition);
186 cmBTStringRange cmStateDirectory::GetCompileOptionsEntries() const
188 return GetPropertyContent(this->DirectoryState->CompileOptions,
189 this->Snapshot_.Position->CompileOptionsPosition);
192 void cmStateDirectory::AppendCompileOptionsEntry(const BT<std::string>& vec)
194 AppendEntry(this->DirectoryState->CompileOptions,
195 this->Snapshot_.Position->CompileOptionsPosition, vec);
198 void cmStateDirectory::SetCompileOptions(const BT<std::string>& vec)
200 SetContent(this->DirectoryState->CompileOptions,
201 this->Snapshot_.Position->CompileOptionsPosition, vec);
204 void cmStateDirectory::ClearCompileOptions()
206 ClearContent(this->DirectoryState->CompileOptions,
207 this->Snapshot_.Position->CompileOptionsPosition);
210 cmBTStringRange cmStateDirectory::GetLinkOptionsEntries() const
212 return GetPropertyContent(this->DirectoryState->LinkOptions,
213 this->Snapshot_.Position->LinkOptionsPosition);
216 void cmStateDirectory::AppendLinkOptionsEntry(const BT<std::string>& vec)
218 AppendEntry(this->DirectoryState->LinkOptions,
219 this->Snapshot_.Position->LinkOptionsPosition, vec);
222 void cmStateDirectory::SetLinkOptions(const BT<std::string>& vec)
224 SetContent(this->DirectoryState->LinkOptions,
225 this->Snapshot_.Position->LinkOptionsPosition, vec);
228 void cmStateDirectory::ClearLinkOptions()
230 ClearContent(this->DirectoryState->LinkOptions,
231 this->Snapshot_.Position->LinkOptionsPosition);
234 cmBTStringRange cmStateDirectory::GetLinkDirectoriesEntries() const
236 return GetPropertyContent(this->DirectoryState->LinkDirectories,
237 this->Snapshot_.Position->LinkDirectoriesPosition);
240 void cmStateDirectory::AppendLinkDirectoriesEntry(const BT<std::string>& vec)
242 AppendEntry(this->DirectoryState->LinkDirectories,
243 this->Snapshot_.Position->LinkDirectoriesPosition, vec);
245 void cmStateDirectory::PrependLinkDirectoriesEntry(const BT<std::string>& vec)
247 auto entryEnd = this->DirectoryState->LinkDirectories.begin() +
248 this->Snapshot_.Position->LinkDirectoriesPosition;
250 auto rend = this->DirectoryState->LinkDirectories.rend();
251 auto rbegin = cm::make_reverse_iterator(entryEnd);
252 rbegin = std::find(rbegin, rend, cmPropertySentinal);
254 auto entryIt = rbegin.base();
256 this->DirectoryState->LinkDirectories.insert(entryIt, vec);
258 this->Snapshot_.Position->LinkDirectoriesPosition =
259 this->DirectoryState->LinkDirectories.size();
262 void cmStateDirectory::SetLinkDirectories(const BT<std::string>& vec)
264 SetContent(this->DirectoryState->LinkDirectories,
265 this->Snapshot_.Position->LinkDirectoriesPosition, vec);
268 void cmStateDirectory::ClearLinkDirectories()
270 ClearContent(this->DirectoryState->LinkDirectories,
271 this->Snapshot_.Position->LinkDirectoriesPosition);
274 template <typename ValueType>
275 void cmStateDirectory::StoreProperty(const std::string& prop, ValueType value,
276 cmListFileBacktrace const& lfbt)
278 if (prop == "INCLUDE_DIRECTORIES") {
280 this->ClearIncludeDirectories();
283 this->SetIncludeDirectories(BT<std::string>(value, lfbt));
286 if (prop == "COMPILE_OPTIONS") {
288 this->ClearCompileOptions();
291 this->SetCompileOptions(BT<std::string>(value, lfbt));
294 if (prop == "COMPILE_DEFINITIONS") {
296 this->ClearCompileDefinitions();
299 this->SetCompileDefinitions(BT<std::string>(value, lfbt));
302 if (prop == "LINK_OPTIONS") {
304 this->ClearLinkOptions();
307 this->SetLinkOptions(BT<std::string>(value, lfbt));
310 if (prop == "LINK_DIRECTORIES") {
312 this->ClearLinkDirectories();
315 this->SetLinkDirectories(BT<std::string>(value, lfbt));
319 this->DirectoryState->Properties.SetProperty(prop, value);
322 void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
323 cmListFileBacktrace const& lfbt)
325 this->StoreProperty(prop, value, lfbt);
327 void cmStateDirectory::SetProperty(const std::string& prop, cmValue value,
328 cmListFileBacktrace const& lfbt)
330 this->StoreProperty(prop, value, lfbt);
333 void cmStateDirectory::AppendProperty(const std::string& prop,
334 const std::string& value, bool asString,
335 cmListFileBacktrace const& lfbt)
337 if (prop == "INCLUDE_DIRECTORIES") {
338 this->AppendIncludeDirectoriesEntry(BT<std::string>(value, lfbt));
341 if (prop == "COMPILE_OPTIONS") {
342 this->AppendCompileOptionsEntry(BT<std::string>(value, lfbt));
345 if (prop == "COMPILE_DEFINITIONS") {
346 this->AppendCompileDefinitionsEntry(BT<std::string>(value, lfbt));
349 if (prop == "LINK_OPTIONS") {
350 this->AppendLinkOptionsEntry(BT<std::string>(value, lfbt));
353 if (prop == "LINK_DIRECTORIES") {
354 this->AppendLinkDirectoriesEntry(BT<std::string>(value, lfbt));
358 this->DirectoryState->Properties.AppendProperty(prop, value, asString);
361 cmValue cmStateDirectory::GetProperty(const std::string& prop) const
364 this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY);
365 return this->GetProperty(prop, chain);
368 cmValue cmStateDirectory::GetProperty(const std::string& prop,
371 static std::string output;
373 if (prop == "PARENT_DIRECTORY") {
374 cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
375 if (parent.IsValid()) {
376 return cmValue(parent.GetDirectory().GetCurrentSource());
378 return cmValue(output);
380 if (prop == kBINARY_DIR) {
381 output = this->GetCurrentBinary();
382 return cmValue(output);
384 if (prop == kSOURCE_DIR) {
385 output = this->GetCurrentSource();
386 return cmValue(output);
388 if (prop == kSUBDIRECTORIES) {
389 std::vector<std::string> child_dirs;
390 std::vector<cmStateSnapshot> const& children =
391 this->DirectoryState->Children;
392 child_dirs.reserve(children.size());
393 for (cmStateSnapshot const& ci : children) {
394 child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
396 output = cmJoin(child_dirs, ";");
397 return cmValue(output);
399 if (prop == kBUILDSYSTEM_TARGETS) {
400 output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
401 return cmValue(output);
403 if (prop == "IMPORTED_TARGETS"_s) {
404 output = cmJoin(this->DirectoryState->ImportedTargetNames, ";");
405 return cmValue(output);
408 if (prop == "LISTFILE_STACK") {
409 std::vector<std::string> listFiles;
410 cmStateSnapshot snp = this->Snapshot_;
411 while (snp.IsValid()) {
412 listFiles.push_back(snp.GetExecutionListFile());
413 snp = snp.GetCallStackParent();
415 std::reverse(listFiles.begin(), listFiles.end());
416 output = cmJoin(listFiles, ";");
417 return cmValue(output);
419 if (prop == "CACHE_VARIABLES") {
420 output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
421 return cmValue(output);
423 if (prop == "VARIABLES") {
424 std::vector<std::string> res = this->Snapshot_.ClosureKeys();
425 cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
426 std::sort(res.begin(), res.end());
427 output = cmJoin(res, ";");
428 return cmValue(output);
430 if (prop == "INCLUDE_DIRECTORIES") {
431 output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
432 return cmValue(output);
434 if (prop == "COMPILE_OPTIONS") {
435 output = cmJoin(this->GetCompileOptionsEntries(), ";");
436 return cmValue(output);
438 if (prop == "COMPILE_DEFINITIONS") {
439 output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
440 return cmValue(output);
442 if (prop == "LINK_OPTIONS") {
443 output = cmJoin(this->GetLinkOptionsEntries(), ";");
444 return cmValue(output);
446 if (prop == "LINK_DIRECTORIES") {
447 output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
448 return cmValue(output);
451 cmValue retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
452 if (!retVal && chain) {
453 cmStateSnapshot parentSnapshot =
454 this->Snapshot_.GetBuildsystemDirectoryParent();
455 if (parentSnapshot.IsValid()) {
456 return parentSnapshot.GetDirectory().GetProperty(prop, chain);
458 return this->Snapshot_.State->GetGlobalProperty(prop);
464 bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const
466 return cmIsOn(this->GetProperty(prop));
469 std::vector<std::string> cmStateDirectory::GetPropertyKeys() const
471 return this->DirectoryState->Properties.GetKeys();
474 void cmStateDirectory::AddNormalTargetName(std::string const& name)
476 this->DirectoryState->NormalTargetNames.push_back(name);
479 void cmStateDirectory::AddImportedTargetName(std::string const& name)
481 this->DirectoryState->ImportedTargetNames.emplace_back(name);