/src/CMake/Source/cmStateDirectory.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | |
4 | | #include "cmStateDirectory.h" |
5 | | |
6 | | #include <algorithm> |
7 | | #include <cassert> |
8 | | #include <vector> |
9 | | |
10 | | #include <cm/iterator> |
11 | | #include <cm/string_view> |
12 | | #include <cmext/algorithm> |
13 | | #include <cmext/string_view> |
14 | | |
15 | | #include "cmAlgorithms.h" |
16 | | #include "cmList.h" |
17 | | #include "cmListFileCache.h" |
18 | | #include "cmProperty.h" |
19 | | #include "cmPropertyMap.h" |
20 | | #include "cmRange.h" |
21 | | #include "cmState.h" |
22 | | #include "cmStatePrivate.h" |
23 | | #include "cmValue.h" |
24 | | |
25 | | static std::string const kBINARY_DIR = "BINARY_DIR"; |
26 | | static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS"; |
27 | | static std::string const kSOURCE_DIR = "SOURCE_DIR"; |
28 | | static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES"; |
29 | | |
30 | | std::string const& cmStateDirectory::GetCurrentSource() const |
31 | 1 | { |
32 | 1 | return this->DirectoryState->Location; |
33 | 1 | } |
34 | | |
35 | | void cmStateDirectory::SetCurrentSource(std::string const& dir) |
36 | 1 | { |
37 | 1 | this->DirectoryState->Location = dir; |
38 | 1 | this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", |
39 | 1 | this->DirectoryState->Location); |
40 | 1 | } |
41 | | |
42 | | std::string const& cmStateDirectory::GetCurrentBinary() const |
43 | 0 | { |
44 | 0 | return this->DirectoryState->OutputLocation; |
45 | 0 | } |
46 | | |
47 | | void cmStateDirectory::SetCurrentBinary(std::string const& dir) |
48 | 1 | { |
49 | 1 | this->DirectoryState->OutputLocation = dir; |
50 | 1 | this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", |
51 | 1 | this->DirectoryState->OutputLocation); |
52 | 1 | } |
53 | | |
54 | | cmStateDirectory::cmStateDirectory( |
55 | | cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter, |
56 | | cmStateSnapshot const& snapshot) |
57 | 3 | : DirectoryState(iter) |
58 | 3 | , Snapshot_(snapshot) |
59 | 3 | { |
60 | 3 | } |
61 | | |
62 | | template <typename T, typename U> |
63 | | cmBTStringRange GetPropertyContent(T const& content, U contentEndPosition) |
64 | 0 | { |
65 | 0 | auto end = content.begin() + contentEndPosition; |
66 | |
|
67 | 0 | auto rbegin = cm::make_reverse_iterator(end); |
68 | 0 | rbegin = std::find(rbegin, content.rend(), cmStateDetail::PropertySentinel); |
69 | |
|
70 | 0 | return cmMakeRange(rbegin.base(), end); |
71 | 0 | } |
72 | | |
73 | | template <typename T, typename U> |
74 | | void AppendEntry(T& content, U& endContentPosition, |
75 | | const BT<std::string>& value) |
76 | 0 | { |
77 | 0 | if (value.Value.empty()) { |
78 | 0 | return; |
79 | 0 | } |
80 | | |
81 | 0 | assert(endContentPosition == content.size()); |
82 | |
|
83 | 0 | content.push_back(value); |
84 | |
|
85 | 0 | endContentPosition = content.size(); |
86 | 0 | } |
87 | | |
88 | | template <typename T, typename U> |
89 | | void SetContent(T& content, U& endContentPosition, const BT<std::string>& vec) |
90 | 0 | { |
91 | 0 | assert(endContentPosition == content.size()); |
92 | |
|
93 | 0 | content.resize(content.size() + 2); |
94 | |
|
95 | 0 | content.back() = vec; |
96 | |
|
97 | 0 | endContentPosition = content.size(); |
98 | 0 | } |
99 | | |
100 | | template <typename T, typename U> |
101 | | void ClearContent(T& content, U& endContentPosition) |
102 | 0 | { |
103 | 0 | assert(endContentPosition == content.size()); |
104 | |
|
105 | 0 | content.resize(content.size() + 1); |
106 | |
|
107 | 0 | endContentPosition = content.size(); |
108 | 0 | } |
109 | | |
110 | | cmBTStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const |
111 | 0 | { |
112 | 0 | return GetPropertyContent( |
113 | 0 | this->DirectoryState->IncludeDirectories, |
114 | 0 | this->Snapshot_.Position->IncludeDirectoryPosition); |
115 | 0 | } |
116 | | |
117 | | void cmStateDirectory::AppendIncludeDirectoriesEntry( |
118 | | const BT<std::string>& vec) |
119 | 0 | { |
120 | 0 | AppendEntry(this->DirectoryState->IncludeDirectories, |
121 | 0 | this->Snapshot_.Position->IncludeDirectoryPosition, vec); |
122 | 0 | } |
123 | | |
124 | | void cmStateDirectory::PrependIncludeDirectoriesEntry( |
125 | | const BT<std::string>& vec) |
126 | 0 | { |
127 | 0 | auto entryEnd = this->DirectoryState->IncludeDirectories.begin() + |
128 | 0 | this->Snapshot_.Position->IncludeDirectoryPosition; |
129 | |
|
130 | 0 | auto rend = this->DirectoryState->IncludeDirectories.rend(); |
131 | 0 | auto rbegin = cm::make_reverse_iterator(entryEnd); |
132 | 0 | rbegin = std::find(rbegin, rend, cmStateDetail::PropertySentinel); |
133 | |
|
134 | 0 | auto entryIt = rbegin.base(); |
135 | |
|
136 | 0 | this->DirectoryState->IncludeDirectories.insert(entryIt, vec); |
137 | |
|
138 | 0 | this->Snapshot_.Position->IncludeDirectoryPosition = |
139 | 0 | this->DirectoryState->IncludeDirectories.size(); |
140 | 0 | } |
141 | | |
142 | | void cmStateDirectory::SetIncludeDirectories(const BT<std::string>& vec) |
143 | 0 | { |
144 | 0 | SetContent(this->DirectoryState->IncludeDirectories, |
145 | 0 | this->Snapshot_.Position->IncludeDirectoryPosition, vec); |
146 | 0 | } |
147 | | |
148 | | void cmStateDirectory::ClearIncludeDirectories() |
149 | 0 | { |
150 | 0 | ClearContent(this->DirectoryState->IncludeDirectories, |
151 | 0 | this->Snapshot_.Position->IncludeDirectoryPosition); |
152 | 0 | } |
153 | | |
154 | | cmBTStringRange cmStateDirectory::GetCompileDefinitionsEntries() const |
155 | 0 | { |
156 | 0 | return GetPropertyContent( |
157 | 0 | this->DirectoryState->CompileDefinitions, |
158 | 0 | this->Snapshot_.Position->CompileDefinitionsPosition); |
159 | 0 | } |
160 | | |
161 | | void cmStateDirectory::AppendCompileDefinitionsEntry( |
162 | | const BT<std::string>& vec) |
163 | 0 | { |
164 | 0 | AppendEntry(this->DirectoryState->CompileDefinitions, |
165 | 0 | this->Snapshot_.Position->CompileDefinitionsPosition, vec); |
166 | 0 | } |
167 | | |
168 | | void cmStateDirectory::SetCompileDefinitions(const BT<std::string>& vec) |
169 | 0 | { |
170 | 0 | SetContent(this->DirectoryState->CompileDefinitions, |
171 | 0 | this->Snapshot_.Position->CompileDefinitionsPosition, vec); |
172 | 0 | } |
173 | | |
174 | | void cmStateDirectory::ClearCompileDefinitions() |
175 | 0 | { |
176 | 0 | ClearContent(this->DirectoryState->CompileDefinitions, |
177 | 0 | this->Snapshot_.Position->CompileDefinitionsPosition); |
178 | 0 | } |
179 | | |
180 | | cmBTStringRange cmStateDirectory::GetCompileOptionsEntries() const |
181 | 0 | { |
182 | 0 | return GetPropertyContent(this->DirectoryState->CompileOptions, |
183 | 0 | this->Snapshot_.Position->CompileOptionsPosition); |
184 | 0 | } |
185 | | |
186 | | void cmStateDirectory::AppendCompileOptionsEntry(const BT<std::string>& vec) |
187 | 0 | { |
188 | 0 | AppendEntry(this->DirectoryState->CompileOptions, |
189 | 0 | this->Snapshot_.Position->CompileOptionsPosition, vec); |
190 | 0 | } |
191 | | |
192 | | void cmStateDirectory::SetCompileOptions(const BT<std::string>& vec) |
193 | 0 | { |
194 | 0 | SetContent(this->DirectoryState->CompileOptions, |
195 | 0 | this->Snapshot_.Position->CompileOptionsPosition, vec); |
196 | 0 | } |
197 | | |
198 | | void cmStateDirectory::ClearCompileOptions() |
199 | 0 | { |
200 | 0 | ClearContent(this->DirectoryState->CompileOptions, |
201 | 0 | this->Snapshot_.Position->CompileOptionsPosition); |
202 | 0 | } |
203 | | |
204 | | cmBTStringRange cmStateDirectory::GetLinkOptionsEntries() const |
205 | 0 | { |
206 | 0 | return GetPropertyContent(this->DirectoryState->LinkOptions, |
207 | 0 | this->Snapshot_.Position->LinkOptionsPosition); |
208 | 0 | } |
209 | | |
210 | | void cmStateDirectory::AppendLinkOptionsEntry(const BT<std::string>& vec) |
211 | 0 | { |
212 | 0 | AppendEntry(this->DirectoryState->LinkOptions, |
213 | 0 | this->Snapshot_.Position->LinkOptionsPosition, vec); |
214 | 0 | } |
215 | | |
216 | | void cmStateDirectory::SetLinkOptions(const BT<std::string>& vec) |
217 | 0 | { |
218 | 0 | SetContent(this->DirectoryState->LinkOptions, |
219 | 0 | this->Snapshot_.Position->LinkOptionsPosition, vec); |
220 | 0 | } |
221 | | |
222 | | void cmStateDirectory::ClearLinkOptions() |
223 | 0 | { |
224 | 0 | ClearContent(this->DirectoryState->LinkOptions, |
225 | 0 | this->Snapshot_.Position->LinkOptionsPosition); |
226 | 0 | } |
227 | | |
228 | | cmBTStringRange cmStateDirectory::GetLinkDirectoriesEntries() const |
229 | 0 | { |
230 | 0 | return GetPropertyContent(this->DirectoryState->LinkDirectories, |
231 | 0 | this->Snapshot_.Position->LinkDirectoriesPosition); |
232 | 0 | } |
233 | | |
234 | | void cmStateDirectory::AppendLinkDirectoriesEntry(const BT<std::string>& vec) |
235 | 0 | { |
236 | 0 | AppendEntry(this->DirectoryState->LinkDirectories, |
237 | 0 | this->Snapshot_.Position->LinkDirectoriesPosition, vec); |
238 | 0 | } |
239 | | void cmStateDirectory::PrependLinkDirectoriesEntry(const BT<std::string>& vec) |
240 | 0 | { |
241 | 0 | auto entryEnd = this->DirectoryState->LinkDirectories.begin() + |
242 | 0 | this->Snapshot_.Position->LinkDirectoriesPosition; |
243 | |
|
244 | 0 | auto rend = this->DirectoryState->LinkDirectories.rend(); |
245 | 0 | auto rbegin = cm::make_reverse_iterator(entryEnd); |
246 | 0 | rbegin = std::find(rbegin, rend, cmStateDetail::PropertySentinel); |
247 | |
|
248 | 0 | auto entryIt = rbegin.base(); |
249 | |
|
250 | 0 | this->DirectoryState->LinkDirectories.insert(entryIt, vec); |
251 | |
|
252 | 0 | this->Snapshot_.Position->LinkDirectoriesPosition = |
253 | 0 | this->DirectoryState->LinkDirectories.size(); |
254 | 0 | } |
255 | | |
256 | | void cmStateDirectory::SetLinkDirectories(const BT<std::string>& vec) |
257 | 0 | { |
258 | 0 | SetContent(this->DirectoryState->LinkDirectories, |
259 | 0 | this->Snapshot_.Position->LinkDirectoriesPosition, vec); |
260 | 0 | } |
261 | | |
262 | | void cmStateDirectory::ClearLinkDirectories() |
263 | 0 | { |
264 | 0 | ClearContent(this->DirectoryState->LinkDirectories, |
265 | 0 | this->Snapshot_.Position->LinkDirectoriesPosition); |
266 | 0 | } |
267 | | |
268 | | void cmStateDirectory::SetProperty(std::string const& prop, cmValue value, |
269 | | cmListFileBacktrace const& lfbt) |
270 | 0 | { |
271 | 0 | if (prop == "INCLUDE_DIRECTORIES") { |
272 | 0 | if (!value) { |
273 | 0 | this->ClearIncludeDirectories(); |
274 | 0 | return; |
275 | 0 | } |
276 | 0 | this->SetIncludeDirectories(BT<std::string>(value, lfbt)); |
277 | 0 | return; |
278 | 0 | } |
279 | 0 | if (prop == "COMPILE_OPTIONS") { |
280 | 0 | if (!value) { |
281 | 0 | this->ClearCompileOptions(); |
282 | 0 | return; |
283 | 0 | } |
284 | 0 | this->SetCompileOptions(BT<std::string>(value, lfbt)); |
285 | 0 | return; |
286 | 0 | } |
287 | 0 | if (prop == "COMPILE_DEFINITIONS") { |
288 | 0 | if (!value) { |
289 | 0 | this->ClearCompileDefinitions(); |
290 | 0 | return; |
291 | 0 | } |
292 | 0 | this->SetCompileDefinitions(BT<std::string>(value, lfbt)); |
293 | 0 | return; |
294 | 0 | } |
295 | 0 | if (prop == "LINK_OPTIONS") { |
296 | 0 | if (!value) { |
297 | 0 | this->ClearLinkOptions(); |
298 | 0 | return; |
299 | 0 | } |
300 | 0 | this->SetLinkOptions(BT<std::string>(value, lfbt)); |
301 | 0 | return; |
302 | 0 | } |
303 | 0 | if (prop == "LINK_DIRECTORIES") { |
304 | 0 | if (!value) { |
305 | 0 | this->ClearLinkDirectories(); |
306 | 0 | return; |
307 | 0 | } |
308 | 0 | this->SetLinkDirectories(BT<std::string>(value, lfbt)); |
309 | 0 | return; |
310 | 0 | } |
311 | | |
312 | 0 | this->DirectoryState->Properties.SetProperty(prop, value); |
313 | 0 | } |
314 | | |
315 | | void cmStateDirectory::AppendProperty(std::string const& prop, |
316 | | std::string const& value, bool asString, |
317 | | cmListFileBacktrace const& lfbt) |
318 | 0 | { |
319 | 0 | if (prop == "INCLUDE_DIRECTORIES") { |
320 | 0 | this->AppendIncludeDirectoriesEntry(BT<std::string>(value, lfbt)); |
321 | 0 | return; |
322 | 0 | } |
323 | 0 | if (prop == "COMPILE_OPTIONS") { |
324 | 0 | this->AppendCompileOptionsEntry(BT<std::string>(value, lfbt)); |
325 | 0 | return; |
326 | 0 | } |
327 | 0 | if (prop == "COMPILE_DEFINITIONS") { |
328 | 0 | this->AppendCompileDefinitionsEntry(BT<std::string>(value, lfbt)); |
329 | 0 | return; |
330 | 0 | } |
331 | 0 | if (prop == "LINK_OPTIONS") { |
332 | 0 | this->AppendLinkOptionsEntry(BT<std::string>(value, lfbt)); |
333 | 0 | return; |
334 | 0 | } |
335 | 0 | if (prop == "LINK_DIRECTORIES") { |
336 | 0 | this->AppendLinkDirectoriesEntry(BT<std::string>(value, lfbt)); |
337 | 0 | return; |
338 | 0 | } |
339 | | |
340 | 0 | this->DirectoryState->Properties.AppendProperty(prop, value, asString); |
341 | 0 | } |
342 | | |
343 | | cmValue cmStateDirectory::GetProperty(std::string const& prop) const |
344 | 0 | { |
345 | 0 | bool const chain = |
346 | 0 | this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY); |
347 | 0 | return this->GetProperty(prop, chain); |
348 | 0 | } |
349 | | |
350 | | cmValue cmStateDirectory::GetProperty(std::string const& prop, |
351 | | bool chain) const |
352 | 0 | { |
353 | 0 | static std::string output; |
354 | 0 | output.clear(); |
355 | 0 | if (prop == "PARENT_DIRECTORY") { |
356 | 0 | cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent(); |
357 | 0 | if (parent.IsValid()) { |
358 | 0 | return cmValue(parent.GetDirectory().GetCurrentSource()); |
359 | 0 | } |
360 | 0 | return cmValue(output); |
361 | 0 | } |
362 | 0 | if (prop == kBINARY_DIR) { |
363 | 0 | output = this->GetCurrentBinary(); |
364 | 0 | return cmValue(output); |
365 | 0 | } |
366 | 0 | if (prop == kSOURCE_DIR) { |
367 | 0 | output = this->GetCurrentSource(); |
368 | 0 | return cmValue(output); |
369 | 0 | } |
370 | 0 | if (prop == kSUBDIRECTORIES) { |
371 | 0 | std::vector<std::string> child_dirs; |
372 | 0 | std::vector<cmStateSnapshot> const& children = |
373 | 0 | this->DirectoryState->Children; |
374 | 0 | child_dirs.reserve(children.size()); |
375 | 0 | for (cmStateSnapshot const& ci : children) { |
376 | 0 | child_dirs.push_back(ci.GetDirectory().GetCurrentSource()); |
377 | 0 | } |
378 | 0 | output = cmList::to_string(child_dirs); |
379 | 0 | return cmValue(output); |
380 | 0 | } |
381 | 0 | if (prop == kBUILDSYSTEM_TARGETS) { |
382 | 0 | output = cmList::to_string(this->DirectoryState->NormalTargetNames); |
383 | 0 | return cmValue(output); |
384 | 0 | } |
385 | 0 | if (prop == "IMPORTED_TARGETS"_s) { |
386 | 0 | output = cmList::to_string(this->DirectoryState->ImportedTargetNames); |
387 | 0 | return cmValue(output); |
388 | 0 | } |
389 | | |
390 | 0 | if (prop == "LISTFILE_STACK") { |
391 | 0 | std::vector<std::string> listFiles; |
392 | 0 | cmStateSnapshot snp = this->Snapshot_; |
393 | 0 | while (snp.IsValid()) { |
394 | 0 | listFiles.push_back(snp.GetExecutionListFile()); |
395 | 0 | snp = snp.GetCallStackParent(); |
396 | 0 | } |
397 | 0 | std::reverse(listFiles.begin(), listFiles.end()); |
398 | 0 | output = cmList::to_string(listFiles); |
399 | 0 | return cmValue(output); |
400 | 0 | } |
401 | 0 | if (prop == "CACHE_VARIABLES") { |
402 | 0 | output = cmList::to_string(this->Snapshot_.State->GetCacheEntryKeys()); |
403 | 0 | return cmValue(output); |
404 | 0 | } |
405 | 0 | if (prop == "VARIABLES") { |
406 | 0 | std::vector<std::string> res = this->Snapshot_.ClosureKeys(); |
407 | 0 | cm::append(res, this->Snapshot_.State->GetCacheEntryKeys()); |
408 | 0 | std::sort(res.begin(), res.end()); |
409 | 0 | output = cmList::to_string(res); |
410 | 0 | return cmValue(output); |
411 | 0 | } |
412 | 0 | if (prop == "INCLUDE_DIRECTORIES") { |
413 | 0 | output = cmList::to_string(this->GetIncludeDirectoriesEntries()); |
414 | 0 | return cmValue(output); |
415 | 0 | } |
416 | 0 | if (prop == "COMPILE_OPTIONS") { |
417 | 0 | output = cmList::to_string(this->GetCompileOptionsEntries()); |
418 | 0 | return cmValue(output); |
419 | 0 | } |
420 | 0 | if (prop == "COMPILE_DEFINITIONS") { |
421 | 0 | output = cmList::to_string(this->GetCompileDefinitionsEntries()); |
422 | 0 | return cmValue(output); |
423 | 0 | } |
424 | 0 | if (prop == "LINK_OPTIONS") { |
425 | 0 | output = cmList::to_string(this->GetLinkOptionsEntries()); |
426 | 0 | return cmValue(output); |
427 | 0 | } |
428 | 0 | if (prop == "LINK_DIRECTORIES") { |
429 | 0 | output = cmList::to_string(this->GetLinkDirectoriesEntries()); |
430 | 0 | return cmValue(output); |
431 | 0 | } |
432 | | |
433 | 0 | cmValue retVal = this->DirectoryState->Properties.GetPropertyValue(prop); |
434 | 0 | if (!retVal && chain) { |
435 | 0 | cmStateSnapshot parentSnapshot = |
436 | 0 | this->Snapshot_.GetBuildsystemDirectoryParent(); |
437 | 0 | if (parentSnapshot.IsValid()) { |
438 | 0 | return parentSnapshot.GetDirectory().GetProperty(prop, chain); |
439 | 0 | } |
440 | 0 | return this->Snapshot_.State->GetGlobalProperty(prop); |
441 | 0 | } |
442 | | |
443 | 0 | return retVal; |
444 | 0 | } |
445 | | |
446 | | bool cmStateDirectory::GetPropertyAsBool(std::string const& prop) const |
447 | 0 | { |
448 | 0 | return this->GetProperty(prop).IsOn(); |
449 | 0 | } |
450 | | |
451 | | std::vector<std::string> cmStateDirectory::GetPropertyKeys() const |
452 | 0 | { |
453 | 0 | return this->DirectoryState->Properties.GetKeys(); |
454 | 0 | } |
455 | | |
456 | | void cmStateDirectory::AddNormalTargetName(std::string const& name) |
457 | 0 | { |
458 | 0 | this->DirectoryState->NormalTargetNames.push_back(name); |
459 | 0 | } |
460 | | |
461 | | void cmStateDirectory::AddImportedTargetName(std::string const& name) |
462 | 0 | { |
463 | 0 | this->DirectoryState->ImportedTargetNames.emplace_back(name); |
464 | 0 | } |