/src/CMake/Source/cmSetPropertyCommand.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 | | #include "cmSetPropertyCommand.h" |
4 | | |
5 | | #include <set> |
6 | | #include <unordered_set> |
7 | | |
8 | | #include <cm/optional> |
9 | | #include <cm/string_view> |
10 | | #include <cmext/string_view> |
11 | | |
12 | | #include "cmDiagnostics.h" |
13 | | #include "cmExecutionStatus.h" |
14 | | #include "cmFileSet.h" |
15 | | #include "cmGlobalGenerator.h" |
16 | | #include "cmInstalledFile.h" |
17 | | #include "cmListFileCache.h" |
18 | | #include "cmMakefile.h" |
19 | | #include "cmPolicies.h" |
20 | | #include "cmProperty.h" |
21 | | #include "cmRange.h" |
22 | | #include "cmRule.h" |
23 | | #include "cmSourceFile.h" |
24 | | #include "cmSourceFileLocation.h" |
25 | | #include "cmState.h" |
26 | | #include "cmStringAlgorithms.h" |
27 | | #include "cmSystemTools.h" |
28 | | #include "cmTarget.h" |
29 | | #include "cmTest.h" |
30 | | #include "cmValue.h" |
31 | | #include "cmake.h" |
32 | | |
33 | | namespace { |
34 | | bool HandleGlobalMode(cmExecutionStatus& status, |
35 | | std::set<std::string> const& names, |
36 | | std::string const& propertyName, |
37 | | std::string const& propertyValue, bool appendAsString, |
38 | | bool appendMode, bool remove); |
39 | | bool HandleDirectoryMode(cmExecutionStatus& status, |
40 | | std::set<std::string> const& names, |
41 | | std::string const& propertyName, |
42 | | std::string const& propertyValue, bool appendAsString, |
43 | | bool appendMode, bool remove); |
44 | | bool HandleRuleMode(cmExecutionStatus& status, |
45 | | std::set<std::string> const& names, |
46 | | std::string const& propertyName, |
47 | | std::string const& propertyValue, bool appendAsString, |
48 | | bool appendMode, bool remove); |
49 | | bool HandleTargetMode(cmExecutionStatus& status, |
50 | | std::set<std::string> const& names, |
51 | | std::string const& propertyName, |
52 | | std::string const& propertyValue, bool appendAsString, |
53 | | bool appendMode, bool remove); |
54 | | bool HandleTarget(cmTarget* target, cmMakefile& makefile, |
55 | | std::string const& propertyName, |
56 | | std::string const& propertyValue, bool appendAsString, |
57 | | bool appendMode, bool remove); |
58 | | bool HandleFileSetMode(cmExecutionStatus& status, |
59 | | std::set<std::string> const& names, |
60 | | std::string const& propertyName, |
61 | | std::string const& propertyValue, bool appendAsString, |
62 | | bool appendMode, bool remove, cmTarget* target); |
63 | | bool HandleFileSet(cmFileSet* fileSet, std::string const& propertyName, |
64 | | std::string const& propertyValue, bool appendAsString, |
65 | | bool appendMode, bool remove); |
66 | | bool HandleSourceMode(cmExecutionStatus& status, |
67 | | std::set<std::string> const& names, |
68 | | std::string const& propertyName, |
69 | | std::string const& propertyValue, bool appendAsString, |
70 | | bool appendMode, bool remove, |
71 | | std::vector<cmMakefile*> const& directory_makefiles, |
72 | | bool source_file_paths_should_be_absolute); |
73 | | bool HandleSource(cmSourceFile* sf, std::string const& propertyName, |
74 | | std::string const& propertyValue, bool appendAsString, |
75 | | bool appendMode, bool remove); |
76 | | bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, |
77 | | std::string const& propertyName, |
78 | | std::string const& propertyValue, bool appendAsString, |
79 | | bool appendMode, bool remove, |
80 | | cmMakefile* test_directory_makefile); |
81 | | bool HandleTest(cmTest* test, std::string const& propertyName, |
82 | | std::string const& propertyValue, bool appendAsString, |
83 | | bool appendMode, bool remove); |
84 | | bool HandleCacheMode(cmExecutionStatus& status, |
85 | | std::set<std::string> const& names, |
86 | | std::string const& propertyName, |
87 | | std::string const& propertyValue, bool appendAsString, |
88 | | bool appendMode, bool remove); |
89 | | bool HandleCacheEntry(std::string const& cacheKey, cmMakefile const& makefile, |
90 | | std::string const& propertyName, |
91 | | std::string const& propertyValue, bool appendAsString, |
92 | | bool appendMode, bool remove); |
93 | | bool HandleInstallMode(cmExecutionStatus& status, |
94 | | std::set<std::string> const& names, |
95 | | std::string const& propertyName, |
96 | | std::string const& propertyValue, bool appendAsString, |
97 | | bool appendMode, bool remove); |
98 | | bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile, |
99 | | std::string const& propertyName, |
100 | | std::string const& propertyValue, bool appendAsString, |
101 | | bool appendMode, bool remove); |
102 | | } |
103 | | |
104 | | namespace SetPropertyCommand { |
105 | | bool HandleFileSetTargetScopes(cmExecutionStatus& status, |
106 | | std::string& file_set_target_name, |
107 | | cmTarget*& file_set_target) |
108 | 0 | { |
109 | 0 | file_set_target = status.GetMakefile().FindTargetToUse(file_set_target_name); |
110 | 0 | if (!file_set_target) { |
111 | 0 | status.SetError( |
112 | 0 | cmStrCat("given non-existent TARGET ", file_set_target_name)); |
113 | 0 | return false; |
114 | 0 | } |
115 | 0 | return true; |
116 | 0 | } |
117 | | |
118 | | bool HandleFileSetTargetScopeValidation(cmExecutionStatus& status, |
119 | | bool file_set_target_option_enabled, |
120 | | std::string& file_set_target_name) |
121 | 0 | { |
122 | 0 | if (!file_set_target_option_enabled) { |
123 | 0 | status.SetError("required TARGET option is missing"); |
124 | 0 | return false; |
125 | 0 | } |
126 | | |
127 | | // Validate file set target scopes. |
128 | 0 | if (file_set_target_name.empty()) { |
129 | 0 | status.SetError("called with incorrect number of arguments " |
130 | 0 | "no value provided to the TARGET option"); |
131 | 0 | return false; |
132 | 0 | } |
133 | 0 | return true; |
134 | 0 | } |
135 | | |
136 | | bool HandleAndValidateFileSetTargetScopes(cmExecutionStatus& status, |
137 | | bool file_set_target_option_enabled, |
138 | | std::string& file_set_target_name, |
139 | | cmTarget*& file_set_target) |
140 | 0 | { |
141 | 0 | bool scope_options_valid = |
142 | 0 | SetPropertyCommand::HandleFileSetTargetScopeValidation( |
143 | 0 | status, file_set_target_option_enabled, file_set_target_name); |
144 | 0 | if (!scope_options_valid) { |
145 | 0 | return false; |
146 | 0 | } |
147 | | |
148 | 0 | scope_options_valid = SetPropertyCommand::HandleFileSetTargetScopes( |
149 | 0 | status, file_set_target_name, file_set_target); |
150 | 0 | return scope_options_valid; |
151 | 0 | } |
152 | | |
153 | | bool HandleSourceFileDirectoryScopes( |
154 | | cmExecutionStatus& status, std::vector<std::string>& source_file_directories, |
155 | | std::vector<std::string>& source_file_target_directories, |
156 | | std::vector<cmMakefile*>& directory_makefiles) |
157 | 5.92k | { |
158 | 5.92k | std::unordered_set<cmMakefile*> directory_makefiles_set; |
159 | | |
160 | 5.92k | cmMakefile* current_dir_mf = &status.GetMakefile(); |
161 | 5.92k | if (!source_file_directories.empty()) { |
162 | 0 | for (std::string const& dir_path : source_file_directories) { |
163 | 0 | std::string const absolute_dir_path = cmSystemTools::CollapseFullPath( |
164 | 0 | dir_path, current_dir_mf->GetCurrentSourceDirectory()); |
165 | 0 | cmMakefile* dir_mf = |
166 | 0 | status.GetMakefile().GetGlobalGenerator()->FindMakefile( |
167 | 0 | absolute_dir_path); |
168 | 0 | if (!dir_mf) { |
169 | 0 | status.SetError(cmStrCat("given non-existent DIRECTORY ", dir_path)); |
170 | 0 | return false; |
171 | 0 | } |
172 | 0 | if (directory_makefiles_set.find(dir_mf) == |
173 | 0 | directory_makefiles_set.end()) { |
174 | 0 | directory_makefiles.push_back(dir_mf); |
175 | 0 | directory_makefiles_set.insert(dir_mf); |
176 | 0 | } |
177 | 0 | } |
178 | 0 | } |
179 | | |
180 | 5.92k | if (!source_file_target_directories.empty()) { |
181 | 0 | for (std::string const& target_name : source_file_target_directories) { |
182 | 0 | cmTarget* target = current_dir_mf->FindTargetToUse(target_name); |
183 | 0 | if (!target) { |
184 | 0 | status.SetError(cmStrCat( |
185 | 0 | "given non-existent target for TARGET_DIRECTORY ", target_name)); |
186 | 0 | return false; |
187 | 0 | } |
188 | 0 | cmValue target_source_dir = target->GetProperty("BINARY_DIR"); |
189 | 0 | cmMakefile* target_dir_mf = |
190 | 0 | status.GetMakefile().GetGlobalGenerator()->FindMakefile( |
191 | 0 | *target_source_dir); |
192 | |
|
193 | 0 | if (directory_makefiles_set.find(target_dir_mf) == |
194 | 0 | directory_makefiles_set.end()) { |
195 | 0 | directory_makefiles.push_back(target_dir_mf); |
196 | 0 | directory_makefiles_set.insert(target_dir_mf); |
197 | 0 | } |
198 | 0 | } |
199 | 0 | } |
200 | | |
201 | 5.92k | if (source_file_directories.empty() && |
202 | 5.92k | source_file_target_directories.empty()) { |
203 | 5.92k | directory_makefiles.push_back(current_dir_mf); |
204 | 5.92k | } |
205 | 5.92k | return true; |
206 | 5.92k | } |
207 | | |
208 | | bool HandleSourceFileDirectoryScopeValidation( |
209 | | cmExecutionStatus& status, bool source_file_directory_option_enabled, |
210 | | bool source_file_target_option_enabled, |
211 | | std::vector<std::string>& source_file_directories, |
212 | | std::vector<std::string>& source_file_target_directories) |
213 | 5.92k | { |
214 | | // Validate source file directory scopes. |
215 | 5.92k | if (source_file_directory_option_enabled && |
216 | 0 | source_file_directories.empty()) { |
217 | 0 | std::string errors = "called with incorrect number of arguments " |
218 | 0 | "no value provided to the DIRECTORY option"; |
219 | 0 | status.SetError(errors); |
220 | 0 | return false; |
221 | 0 | } |
222 | 5.92k | if (source_file_target_option_enabled && |
223 | 0 | source_file_target_directories.empty()) { |
224 | 0 | std::string errors = "called with incorrect number of arguments " |
225 | 0 | "no value provided to the TARGET_DIRECTORY option"; |
226 | 0 | status.SetError(errors); |
227 | 0 | return false; |
228 | 0 | } |
229 | 5.92k | return true; |
230 | 5.92k | } |
231 | | |
232 | | bool HandleAndValidateSourceFileDirectoryScopes( |
233 | | cmExecutionStatus& status, bool source_file_directory_option_enabled, |
234 | | bool source_file_target_option_enabled, |
235 | | std::vector<std::string>& source_file_directories, |
236 | | std::vector<std::string>& source_file_target_directories, |
237 | | std::vector<cmMakefile*>& source_file_directory_makefiles) |
238 | 5.92k | { |
239 | 5.92k | bool scope_options_valid = |
240 | 5.92k | SetPropertyCommand::HandleSourceFileDirectoryScopeValidation( |
241 | 5.92k | status, source_file_directory_option_enabled, |
242 | 5.92k | source_file_target_option_enabled, source_file_directories, |
243 | 5.92k | source_file_target_directories); |
244 | 5.92k | if (!scope_options_valid) { |
245 | 0 | return false; |
246 | 0 | } |
247 | | |
248 | 5.92k | scope_options_valid = SetPropertyCommand::HandleSourceFileDirectoryScopes( |
249 | 5.92k | status, source_file_directories, source_file_target_directories, |
250 | 5.92k | source_file_directory_makefiles); |
251 | 5.92k | return scope_options_valid; |
252 | 5.92k | } |
253 | | |
254 | | bool HandleTestDirectoryScopes(cmExecutionStatus& status, |
255 | | std::string& test_directory, |
256 | | cmMakefile*& directory_makefile) |
257 | 0 | { |
258 | 0 | cmMakefile* current_dir_mf = &status.GetMakefile(); |
259 | 0 | if (!test_directory.empty()) { |
260 | 0 | std::string const absolute_dir_path = cmSystemTools::CollapseFullPath( |
261 | 0 | test_directory, current_dir_mf->GetCurrentSourceDirectory()); |
262 | 0 | cmMakefile* dir_mf = |
263 | 0 | status.GetMakefile().GetGlobalGenerator()->FindMakefile( |
264 | 0 | absolute_dir_path); |
265 | 0 | if (!dir_mf) { |
266 | 0 | status.SetError( |
267 | 0 | cmStrCat("given non-existent DIRECTORY ", test_directory)); |
268 | 0 | return false; |
269 | 0 | } |
270 | 0 | directory_makefile = dir_mf; |
271 | 0 | } else { |
272 | 0 | directory_makefile = current_dir_mf; |
273 | 0 | } |
274 | 0 | return true; |
275 | 0 | } |
276 | | |
277 | | bool HandleTestDirectoryScopeValidation(cmExecutionStatus& status, |
278 | | bool test_directory_option_enabled, |
279 | | std::string& test_directory) |
280 | 0 | { |
281 | | // Validate source file directory scopes. |
282 | 0 | if (test_directory_option_enabled && test_directory.empty()) { |
283 | 0 | std::string errors = "called with incorrect number of arguments " |
284 | 0 | "no value provided to the DIRECTORY option"; |
285 | 0 | status.SetError(errors); |
286 | 0 | return false; |
287 | 0 | } |
288 | 0 | return true; |
289 | 0 | } |
290 | | |
291 | | bool HandleAndValidateTestDirectoryScopes(cmExecutionStatus& status, |
292 | | bool test_directory_option_enabled, |
293 | | std::string& test_directory, |
294 | | cmMakefile*& test_directory_makefile) |
295 | 0 | { |
296 | 0 | bool scope_options_valid = |
297 | 0 | SetPropertyCommand::HandleTestDirectoryScopeValidation( |
298 | 0 | status, test_directory_option_enabled, test_directory); |
299 | 0 | if (!scope_options_valid) { |
300 | 0 | return false; |
301 | 0 | } |
302 | | |
303 | 0 | scope_options_valid = SetPropertyCommand::HandleTestDirectoryScopes( |
304 | 0 | status, test_directory, test_directory_makefile); |
305 | 0 | return scope_options_valid; |
306 | 0 | } |
307 | | |
308 | | std::string MakeSourceFilePathAbsoluteIfNeeded( |
309 | | cmExecutionStatus& status, std::string const& source_file_path, |
310 | | bool const needed) |
311 | 0 | { |
312 | 0 | if (!needed) { |
313 | 0 | return source_file_path; |
314 | 0 | } |
315 | 0 | std::string absolute_file_path = cmSystemTools::CollapseFullPath( |
316 | 0 | source_file_path, status.GetMakefile().GetCurrentSourceDirectory()); |
317 | 0 | return absolute_file_path; |
318 | 0 | } |
319 | | |
320 | | void MakeSourceFilePathsAbsoluteIfNeeded( |
321 | | cmExecutionStatus& status, |
322 | | std::vector<std::string>& source_files_absolute_paths, |
323 | | std::vector<std::string>::const_iterator files_it_begin, |
324 | | std::vector<std::string>::const_iterator files_it_end, bool const needed) |
325 | 5.92k | { |
326 | | |
327 | | // Make the file paths absolute, so that relative source file paths are |
328 | | // picked up relative to the command calling site, regardless of the |
329 | | // directory scope. |
330 | 5.92k | std::vector<std::string>::difference_type num_files = |
331 | 5.92k | files_it_end - files_it_begin; |
332 | 5.92k | source_files_absolute_paths.reserve(num_files); |
333 | | |
334 | 5.92k | if (!needed) { |
335 | 5.92k | source_files_absolute_paths.assign(files_it_begin, files_it_end); |
336 | 5.92k | return; |
337 | 5.92k | } |
338 | | |
339 | 0 | for (; files_it_begin != files_it_end; ++files_it_begin) { |
340 | 0 | std::string const absolute_file_path = |
341 | 0 | MakeSourceFilePathAbsoluteIfNeeded(status, *files_it_begin, true); |
342 | 0 | source_files_absolute_paths.push_back(absolute_file_path); |
343 | 0 | } |
344 | 0 | } |
345 | | |
346 | | bool HandleAndValidateSourceFilePropertyGENERATED( |
347 | | cmSourceFile* sf, std::string const& propertyValue, PropertyOp op) |
348 | 0 | { |
349 | 0 | auto const& mf = *sf->GetLocation().GetMakefile(); |
350 | |
|
351 | 0 | auto isProblematic = [&mf, &propertyValue, |
352 | 0 | op](cm::string_view policy) -> bool { |
353 | 0 | if (!cmIsOn(propertyValue) && !cmIsOff(propertyValue)) { |
354 | 0 | mf.IssueDiagnostic( |
355 | 0 | cmDiagnostics::CMD_AUTHOR, |
356 | 0 | cmStrCat("Policy ", policy, |
357 | 0 | " is set to NEW and the following non-boolean value given " |
358 | 0 | "for property 'GENERATED' is therefore not allowed:\n", |
359 | 0 | propertyValue, "\nReplace it with a boolean value!\n")); |
360 | 0 | return true; |
361 | 0 | } |
362 | 0 | if (cmIsOff(propertyValue)) { |
363 | 0 | mf.IssueDiagnostic( |
364 | 0 | cmDiagnostics::CMD_AUTHOR, |
365 | 0 | cmStrCat("Unsetting the 'GENERATED' property is not allowed under ", |
366 | 0 | policy, "!\n")); |
367 | 0 | return true; |
368 | 0 | } |
369 | 0 | if (op == PropertyOp::Append || op == PropertyOp::AppendAsString) { |
370 | 0 | mf.IssueDiagnostic( |
371 | 0 | cmDiagnostics::CMD_AUTHOR, |
372 | 0 | cmStrCat( |
373 | 0 | "Policy ", policy, |
374 | 0 | " is set to NEW and appending to the 'GENERATED' property is " |
375 | 0 | "therefore not allowed. Only setting it to \"1\" is allowed!\n")); |
376 | 0 | return true; |
377 | 0 | } |
378 | 0 | return false; |
379 | 0 | }; |
380 | |
|
381 | 0 | auto const cmp0163PolicyStatus = mf.GetPolicyStatus(cmPolicies::CMP0163); |
382 | 0 | bool const cmp0163PolicyNEW = cmp0163PolicyStatus != cmPolicies::OLD && |
383 | 0 | cmp0163PolicyStatus != cmPolicies::WARN; |
384 | 0 | if (cmp0163PolicyNEW) { |
385 | 0 | if (!isProblematic("CMP0163")) { |
386 | 0 | sf->MarkAsGenerated(); |
387 | 0 | } |
388 | 0 | return true; |
389 | 0 | } |
390 | | |
391 | 0 | auto const cmp0118PolicyStatus = mf.GetPolicyStatus(cmPolicies::CMP0118); |
392 | 0 | bool const cmp0118PolicyWARN = cmp0118PolicyStatus == cmPolicies::WARN; |
393 | 0 | bool const cmp0118PolicyNEW = |
394 | 0 | cmp0118PolicyStatus != cmPolicies::OLD && !cmp0118PolicyWARN; |
395 | |
|
396 | 0 | if (cmp0118PolicyNEW) { |
397 | 0 | if (!isProblematic("CMP0118")) { |
398 | 0 | sf->MarkAsGenerated(); |
399 | 0 | } |
400 | 0 | return true; |
401 | 0 | } |
402 | | |
403 | 0 | if (cmp0118PolicyWARN) { |
404 | 0 | if (!cmIsOn(propertyValue) && !cmIsOff(propertyValue)) { |
405 | 0 | mf.IssuePolicyWarning( |
406 | 0 | cmPolicies::CMP0118, {}, |
407 | 0 | cmStrCat("Attempt to set property 'GENERATED' with the following " |
408 | 0 | "non-boolean value (which will be interpreted as \"0\"):\n"_s, |
409 | 0 | propertyValue, |
410 | 0 | "\nThat exact value will not be retrievable. A value of " |
411 | 0 | "\"0\" will be returned instead.\n" |
412 | 0 | "This will be an error under policy CMP0118."_s)); |
413 | 0 | } |
414 | 0 | if (cmIsOff(propertyValue)) { |
415 | 0 | mf.IssuePolicyWarning(cmPolicies::CMP0118, {}, |
416 | 0 | "Unsetting property 'GENERATED' " |
417 | 0 | "will not be allowed under policy CMP0118!"_s); |
418 | 0 | } |
419 | 0 | if (op == PropertyOp::Append || op == PropertyOp::AppendAsString) { |
420 | 0 | mf.IssuePolicyWarning(cmPolicies::CMP0118, {}, |
421 | 0 | "Appending to property 'GENERATED' " |
422 | 0 | "will not be allowed under policy CMP0118!"_s); |
423 | 0 | } |
424 | 0 | } |
425 | | |
426 | | // Set property the traditional way. |
427 | 0 | switch (op) { |
428 | 0 | case PropertyOp::Append: |
429 | 0 | sf->AppendProperty("GENERATED", propertyValue, false); |
430 | 0 | break; |
431 | 0 | case PropertyOp::AppendAsString: |
432 | 0 | sf->AppendProperty("GENERATED", propertyValue, true); |
433 | 0 | break; |
434 | 0 | case PropertyOp::Remove: |
435 | 0 | sf->RemoveProperty("GENERATED"); |
436 | 0 | break; |
437 | 0 | case PropertyOp::Set: |
438 | 0 | sf->SetProperty("GENERATED", propertyValue); |
439 | 0 | break; |
440 | 0 | } |
441 | 0 | return true; |
442 | 0 | } |
443 | | |
444 | | } // END: namespace SetPropertyCommand |
445 | | |
446 | | bool cmSetPropertyCommand(std::vector<std::string> const& args, |
447 | | cmExecutionStatus& status) |
448 | 29.6k | { |
449 | 29.6k | if (args.size() < 2) { |
450 | 0 | status.SetError("called with incorrect number of arguments"); |
451 | 0 | return false; |
452 | 0 | } |
453 | | |
454 | | // Get the scope on which to set the property. |
455 | 29.6k | std::string const& scopeName = args.front(); |
456 | 29.6k | cmProperty::ScopeType scope; |
457 | 29.6k | if (scopeName == "GLOBAL") { |
458 | 11.8k | scope = cmProperty::GLOBAL; |
459 | 17.7k | } else if (scopeName == "DIRECTORY") { |
460 | 5.92k | scope = cmProperty::DIRECTORY; |
461 | 11.8k | } else if (scopeName == "RULE") { |
462 | 0 | scope = cmProperty::RULE; |
463 | 11.8k | } else if (scopeName == "TARGET") { |
464 | 11.8k | scope = cmProperty::TARGET; |
465 | 11.8k | } else if (scopeName == "FILE_SET") { |
466 | 0 | scope = cmProperty::FILE_SET; |
467 | 0 | } else if (scopeName == "SOURCE") { |
468 | 0 | scope = cmProperty::SOURCE_FILE; |
469 | 0 | } else if (scopeName == "TEST") { |
470 | 0 | scope = cmProperty::TEST; |
471 | 0 | } else if (scopeName == "CACHE") { |
472 | 0 | scope = cmProperty::CACHE; |
473 | 0 | } else if (scopeName == "INSTALL") { |
474 | 0 | scope = cmProperty::INSTALL; |
475 | 0 | } else { |
476 | 0 | status.SetError( |
477 | 0 | cmStrCat("given invalid scope ", scopeName, |
478 | 0 | ". Valid scopes are GLOBAL, DIRECTORY, RULE, TARGET, " |
479 | 0 | "FILE_SET, SOURCE, TEST, CACHE, INSTALL.")); |
480 | 0 | return false; |
481 | 0 | } |
482 | | |
483 | 29.6k | bool appendAsString = false; |
484 | 29.6k | bool appendMode = false; |
485 | 29.6k | bool remove = true; |
486 | 29.6k | std::set<std::string> names; |
487 | 29.6k | std::string propertyName; |
488 | 29.6k | std::string propertyValue; |
489 | | |
490 | 29.6k | std::string file_set_target_name; |
491 | 29.6k | bool file_set_target_option_enabled = false; |
492 | | |
493 | 29.6k | std::vector<std::string> source_file_directories; |
494 | 29.6k | std::vector<std::string> source_file_target_directories; |
495 | 29.6k | bool source_file_directory_option_enabled = false; |
496 | 29.6k | bool source_file_target_option_enabled = false; |
497 | | |
498 | 29.6k | std::string test_directory; |
499 | 29.6k | bool test_directory_option_enabled = false; |
500 | | |
501 | | // Parse the rest of the arguments up to the values. |
502 | 29.6k | enum Doing |
503 | 29.6k | { |
504 | 29.6k | DoingNone, |
505 | 29.6k | DoingNames, |
506 | 29.6k | DoingProperty, |
507 | 29.6k | DoingValues, |
508 | 29.6k | DoingFileSetTarget, |
509 | 29.6k | DoingSourceDirectory, |
510 | 29.6k | DoingSourceTargetDirectory, |
511 | 29.6k | DoingTestDirectory, |
512 | 29.6k | }; |
513 | 29.6k | Doing doing = DoingNames; |
514 | 29.6k | char const* sep = ""; |
515 | 100k | for (std::string const& arg : cmMakeRange(args).advance(1)) { |
516 | 100k | if (arg == "PROPERTY") { |
517 | 29.6k | doing = DoingProperty; |
518 | 71.1k | } else if (arg == "APPEND") { |
519 | 0 | doing = DoingNone; |
520 | 0 | appendMode = true; |
521 | 0 | remove = false; |
522 | 0 | appendAsString = false; |
523 | 71.1k | } else if (arg == "APPEND_STRING") { |
524 | 0 | doing = DoingNone; |
525 | 0 | appendMode = true; |
526 | 0 | remove = false; |
527 | 0 | appendAsString = true; |
528 | 71.1k | } else if (doing != DoingProperty && doing != DoingValues && |
529 | 11.8k | scope == cmProperty::FILE_SET && arg == "TARGET") { |
530 | 0 | doing = DoingFileSetTarget; |
531 | 0 | file_set_target_option_enabled = true; |
532 | 71.1k | } else if (doing != DoingProperty && doing != DoingValues && |
533 | 11.8k | scope == cmProperty::SOURCE_FILE && arg == "DIRECTORY") { |
534 | 0 | doing = DoingSourceDirectory; |
535 | 0 | source_file_directory_option_enabled = true; |
536 | 71.1k | } else if (doing != DoingProperty && doing != DoingValues && |
537 | 11.8k | scope == cmProperty::SOURCE_FILE && arg == "TARGET_DIRECTORY") { |
538 | 0 | doing = DoingSourceTargetDirectory; |
539 | 0 | source_file_target_option_enabled = true; |
540 | 71.1k | } else if (doing != DoingProperty && doing != DoingValues && |
541 | 11.8k | scope == cmProperty::TEST && arg == "DIRECTORY") { |
542 | 0 | doing = DoingTestDirectory; |
543 | 0 | test_directory_option_enabled = true; |
544 | 71.1k | } else if (doing == DoingNames) { |
545 | 11.8k | names.insert(arg); |
546 | 59.2k | } else if (doing == DoingFileSetTarget) { |
547 | 0 | file_set_target_name = arg; |
548 | 0 | file_set_target_option_enabled = true; |
549 | 0 | doing = DoingNone; |
550 | 59.2k | } else if (doing == DoingSourceDirectory) { |
551 | 0 | source_file_directories.push_back(arg); |
552 | 59.2k | } else if (doing == DoingSourceTargetDirectory) { |
553 | 0 | source_file_target_directories.push_back(arg); |
554 | 59.2k | } else if (doing == DoingTestDirectory) { |
555 | 0 | test_directory = arg; |
556 | 0 | doing = DoingNone; |
557 | 59.2k | } else if (doing == DoingProperty) { |
558 | 29.6k | propertyName = arg; |
559 | 29.6k | doing = DoingValues; |
560 | 29.6k | } else if (doing == DoingValues) { |
561 | 29.6k | propertyValue += sep; |
562 | 29.6k | sep = ";"; |
563 | 29.6k | propertyValue += arg; |
564 | 29.6k | remove = false; |
565 | 29.6k | } else { |
566 | 0 | status.SetError(cmStrCat("given invalid argument \"", arg, "\".")); |
567 | 0 | return false; |
568 | 0 | } |
569 | 100k | } |
570 | | |
571 | | // Make sure a property name was found. |
572 | 29.6k | if (propertyName.empty()) { |
573 | 0 | status.SetError("not given a PROPERTY <name> argument."); |
574 | 0 | return false; |
575 | 0 | } |
576 | | |
577 | | // Dispatch property setting. |
578 | 29.6k | switch (scope) { |
579 | 11.8k | case cmProperty::GLOBAL: |
580 | 11.8k | return HandleGlobalMode(status, names, propertyName, propertyValue, |
581 | 11.8k | appendAsString, appendMode, remove); |
582 | 5.92k | case cmProperty::DIRECTORY: |
583 | 5.92k | return HandleDirectoryMode(status, names, propertyName, propertyValue, |
584 | 5.92k | appendAsString, appendMode, remove); |
585 | 0 | case cmProperty::RULE: |
586 | 0 | return HandleRuleMode(status, names, propertyName, propertyValue, |
587 | 0 | appendAsString, appendMode, remove); |
588 | 11.8k | case cmProperty::TARGET: |
589 | 11.8k | return HandleTargetMode(status, names, propertyName, propertyValue, |
590 | 11.8k | appendAsString, appendMode, remove); |
591 | 0 | case cmProperty::FILE_SET: { |
592 | 0 | cmTarget* file_set_target; |
593 | 0 | if (!SetPropertyCommand::HandleAndValidateFileSetTargetScopes( |
594 | 0 | status, file_set_target_option_enabled, file_set_target_name, |
595 | 0 | file_set_target)) { |
596 | 0 | return false; |
597 | 0 | } |
598 | 0 | return HandleFileSetMode(status, names, propertyName, propertyValue, |
599 | 0 | appendAsString, appendMode, remove, |
600 | 0 | file_set_target); |
601 | 0 | } |
602 | 0 | case cmProperty::SOURCE_FILE: { |
603 | 0 | std::vector<cmMakefile*> source_file_directory_makefiles; |
604 | 0 | if (!SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes( |
605 | 0 | status, source_file_directory_option_enabled, |
606 | 0 | source_file_target_option_enabled, source_file_directories, |
607 | 0 | source_file_target_directories, source_file_directory_makefiles)) { |
608 | 0 | return false; |
609 | 0 | } |
610 | 0 | bool source_file_paths_should_be_absolute = |
611 | 0 | source_file_directory_option_enabled || |
612 | 0 | source_file_target_option_enabled; |
613 | 0 | return HandleSourceMode(status, names, propertyName, propertyValue, |
614 | 0 | appendAsString, appendMode, remove, |
615 | 0 | source_file_directory_makefiles, |
616 | 0 | source_file_paths_should_be_absolute); |
617 | 0 | } |
618 | 0 | case cmProperty::TEST: { |
619 | 0 | cmMakefile* test_directory_makefile; |
620 | 0 | if (!SetPropertyCommand::HandleAndValidateTestDirectoryScopes( |
621 | 0 | status, test_directory_option_enabled, test_directory, |
622 | 0 | test_directory_makefile)) { |
623 | 0 | return false; |
624 | 0 | } |
625 | 0 | return HandleTestMode(status, names, propertyName, propertyValue, |
626 | 0 | appendAsString, appendMode, remove, |
627 | 0 | test_directory_makefile); |
628 | 0 | } |
629 | 0 | case cmProperty::CACHE: |
630 | 0 | return HandleCacheMode(status, names, propertyName, propertyValue, |
631 | 0 | appendAsString, appendMode, remove); |
632 | 0 | case cmProperty::INSTALL: |
633 | 0 | return HandleInstallMode(status, names, propertyName, propertyValue, |
634 | 0 | appendAsString, appendMode, remove); |
635 | | |
636 | 0 | case cmProperty::VARIABLE: |
637 | 0 | case cmProperty::CACHED_VARIABLE: |
638 | 0 | break; // should never happen |
639 | 29.6k | } |
640 | 0 | return true; |
641 | 29.6k | } |
642 | | |
643 | | namespace /* anonymous */ { |
644 | | bool HandleGlobalMode(cmExecutionStatus& status, |
645 | | std::set<std::string> const& names, |
646 | | std::string const& propertyName, |
647 | | std::string const& propertyValue, bool appendAsString, |
648 | | bool appendMode, bool remove) |
649 | 11.8k | { |
650 | 11.8k | if (!names.empty()) { |
651 | 0 | status.SetError("given names for GLOBAL scope."); |
652 | 0 | return false; |
653 | 0 | } |
654 | | |
655 | | // Set or append the property. |
656 | 11.8k | cmake* cm = status.GetMakefile().GetCMakeInstance(); |
657 | 11.8k | if (appendMode) { |
658 | 0 | cm->AppendProperty(propertyName, propertyValue, appendAsString); |
659 | 11.8k | } else { |
660 | 11.8k | if (remove) { |
661 | 0 | cm->SetProperty(propertyName, nullptr); |
662 | 11.8k | } else { |
663 | 11.8k | cm->SetProperty(propertyName, propertyValue); |
664 | 11.8k | } |
665 | 11.8k | } |
666 | | |
667 | 11.8k | return true; |
668 | 11.8k | } |
669 | | |
670 | | bool HandleDirectoryMode(cmExecutionStatus& status, |
671 | | std::set<std::string> const& names, |
672 | | std::string const& propertyName, |
673 | | std::string const& propertyValue, bool appendAsString, |
674 | | bool appendMode, bool remove) |
675 | 5.92k | { |
676 | 5.92k | if (names.size() > 1) { |
677 | 0 | status.SetError("allows at most one name for DIRECTORY scope."); |
678 | 0 | return false; |
679 | 0 | } |
680 | | |
681 | | // Default to the current directory. |
682 | 5.92k | cmMakefile* mf = &status.GetMakefile(); |
683 | | |
684 | | // Lookup the directory if given. |
685 | 5.92k | if (!names.empty()) { |
686 | | // Construct the directory name. Interpret relative paths with |
687 | | // respect to the current directory. |
688 | 0 | std::string dir = cmSystemTools::CollapseFullPath( |
689 | 0 | *names.begin(), status.GetMakefile().GetCurrentSourceDirectory()); |
690 | |
|
691 | 0 | mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir); |
692 | 0 | if (!mf) { |
693 | | // Could not find the directory. |
694 | 0 | status.SetError( |
695 | 0 | "DIRECTORY scope provided but requested directory was not found. " |
696 | 0 | "This could be because the directory argument was invalid or, " |
697 | 0 | "it is valid but has not been processed yet."); |
698 | 0 | return false; |
699 | 0 | } |
700 | 0 | } |
701 | | |
702 | | // Set or append the property. |
703 | 5.92k | if (appendMode) { |
704 | 0 | mf->AppendProperty(propertyName, propertyValue, appendAsString); |
705 | 5.92k | } else { |
706 | 5.92k | if (remove) { |
707 | 0 | mf->SetProperty(propertyName, nullptr); |
708 | 5.92k | } else { |
709 | 5.92k | mf->SetProperty(propertyName, propertyValue); |
710 | 5.92k | } |
711 | 5.92k | } |
712 | | |
713 | 5.92k | return true; |
714 | 5.92k | } |
715 | | |
716 | | bool HandleRuleMode(cmExecutionStatus& status, |
717 | | std::set<std::string> const& names, |
718 | | std::string const& propertyName, |
719 | | std::string const& propertyValue, bool appendAsString, |
720 | | bool appendMode, bool remove) |
721 | 0 | { |
722 | 0 | for (std::string const& name : names) { |
723 | 0 | if (cmRule* rule = status.GetMakefile().FindRuleToUse(name)) { |
724 | | // Handle the current rule. |
725 | | // Set or append the property. |
726 | 0 | if (appendMode) { |
727 | 0 | rule->AppendProperty(propertyName, propertyValue, appendAsString); |
728 | 0 | } else { |
729 | 0 | if (remove) { |
730 | 0 | rule->SetProperty(propertyName, nullptr); |
731 | 0 | } else { |
732 | 0 | rule->SetProperty(propertyName, propertyValue); |
733 | 0 | } |
734 | 0 | } |
735 | | // Check the resulting value. |
736 | 0 | rule->CheckProperty(propertyName, status.GetMakefile()); |
737 | 0 | } else { |
738 | 0 | status.SetError(cmStrCat("could not find RULE ", name, |
739 | 0 | ". Perhaps it has not yet been created.")); |
740 | 0 | return false; |
741 | 0 | } |
742 | 0 | } |
743 | 0 | return true; |
744 | 0 | } |
745 | | |
746 | | bool HandleTargetMode(cmExecutionStatus& status, |
747 | | std::set<std::string> const& names, |
748 | | std::string const& propertyName, |
749 | | std::string const& propertyValue, bool appendAsString, |
750 | | bool appendMode, bool remove) |
751 | 11.8k | { |
752 | 11.8k | for (std::string const& name : names) { |
753 | | // Better error message for alias properties set on an alias target. |
754 | 11.8k | if (propertyName == "ALIASED_TARGET" || propertyName == "ALIAS_GLOBAL") { |
755 | 0 | if (status.GetMakefile().IsAlias(name)) { |
756 | 0 | status.SetError(cmStrCat("can not set property ", propertyName, |
757 | 0 | " on an ALIAS target: ", name)); |
758 | 0 | return false; |
759 | 0 | } |
760 | 0 | } |
761 | 11.8k | if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) { |
762 | 11.8k | if (target->IsSymbolic()) { |
763 | 0 | status.SetError("can not be used on a SYMBOLIC target."); |
764 | 0 | return false; |
765 | 0 | } |
766 | | |
767 | | // Handle the current target. |
768 | 11.8k | if (!HandleTarget(target, status.GetMakefile(), propertyName, |
769 | 11.8k | propertyValue, appendAsString, appendMode, remove)) { |
770 | 0 | return false; |
771 | 0 | } |
772 | 11.8k | } else { |
773 | 0 | status.SetError(cmStrCat("could not find TARGET ", name, |
774 | 0 | ". Perhaps it has not yet been created.")); |
775 | 0 | return false; |
776 | 0 | } |
777 | 11.8k | } |
778 | 11.8k | return true; |
779 | 11.8k | } |
780 | | |
781 | | bool HandleTarget(cmTarget* target, cmMakefile& makefile, |
782 | | std::string const& propertyName, |
783 | | std::string const& propertyValue, bool appendAsString, |
784 | | bool appendMode, bool remove) |
785 | 11.8k | { |
786 | | // Set or append the property. |
787 | 11.8k | if (appendMode) { |
788 | 0 | target->AppendProperty(propertyName, propertyValue, |
789 | 0 | makefile.GetBacktrace(), appendAsString); |
790 | 11.8k | } else { |
791 | 11.8k | if (remove) { |
792 | 0 | target->SetProperty(propertyName, nullptr); |
793 | 11.8k | } else { |
794 | 11.8k | target->SetProperty(propertyName, propertyValue); |
795 | 11.8k | } |
796 | 11.8k | } |
797 | | |
798 | | // Check the resulting value. |
799 | 11.8k | target->CheckProperty(propertyName, &makefile); |
800 | | |
801 | 11.8k | return true; |
802 | 11.8k | } |
803 | | |
804 | | bool HandleFileSetMode(cmExecutionStatus& status, |
805 | | std::set<std::string> const& names, |
806 | | std::string const& propertyName, |
807 | | std::string const& propertyValue, bool appendAsString, |
808 | | bool appendMode, bool remove, cmTarget* target) |
809 | 0 | { |
810 | 0 | for (std::string const& name : names) { |
811 | 0 | if (cmFileSet* fileSet = target->GetFileSet(name)) { |
812 | | // Handle the current file set. |
813 | 0 | if (!HandleFileSet(fileSet, propertyName, propertyValue, appendAsString, |
814 | 0 | appendMode, remove)) { |
815 | 0 | return false; |
816 | 0 | } |
817 | 0 | } else { |
818 | 0 | status.SetError(cmStrCat("could not find FILE_SET ", name, |
819 | 0 | " for TARGET ", target->GetName(), |
820 | 0 | ". Perhaps it has not yet been created.")); |
821 | 0 | return false; |
822 | 0 | } |
823 | 0 | } |
824 | 0 | return true; |
825 | 0 | } |
826 | | |
827 | | bool HandleFileSet(cmFileSet* fileSet, std::string const& propertyName, |
828 | | std::string const& propertyValue, bool appendAsString, |
829 | | bool appendMode, bool remove) |
830 | 0 | { |
831 | | // Set or append the property. |
832 | 0 | if (appendMode) { |
833 | 0 | fileSet->AppendProperty(propertyName, propertyValue, appendAsString); |
834 | 0 | } else { |
835 | 0 | if (remove) { |
836 | 0 | fileSet->SetProperty(propertyName, nullptr); |
837 | 0 | } else { |
838 | 0 | fileSet->SetProperty(propertyName, propertyValue); |
839 | 0 | } |
840 | 0 | } |
841 | 0 | return true; |
842 | 0 | } |
843 | | |
844 | | bool HandleSourceMode(cmExecutionStatus& status, |
845 | | std::set<std::string> const& names, |
846 | | std::string const& propertyName, |
847 | | std::string const& propertyValue, bool appendAsString, |
848 | | bool appendMode, bool remove, |
849 | | std::vector<cmMakefile*> const& directory_makefiles, |
850 | | bool const source_file_paths_should_be_absolute) |
851 | 0 | { |
852 | 0 | std::vector<std::string> files_absolute; |
853 | 0 | std::vector<std::string> unique_files(names.begin(), names.end()); |
854 | 0 | SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded( |
855 | 0 | status, files_absolute, unique_files.begin(), unique_files.end(), |
856 | 0 | source_file_paths_should_be_absolute); |
857 | |
|
858 | 0 | for (auto* const mf : directory_makefiles) { |
859 | 0 | for (std::string const& name : files_absolute) { |
860 | | // Get the source file. |
861 | 0 | if (cmSourceFile* sf = mf->GetOrCreateSource(name)) { |
862 | 0 | if (!HandleSource(sf, propertyName, propertyValue, appendAsString, |
863 | 0 | appendMode, remove)) { |
864 | 0 | return false; |
865 | 0 | } |
866 | 0 | } else { |
867 | 0 | status.SetError(cmStrCat( |
868 | 0 | "given SOURCE name that could not be found or created: ", name)); |
869 | 0 | return false; |
870 | 0 | } |
871 | 0 | } |
872 | 0 | } |
873 | | |
874 | 0 | return true; |
875 | 0 | } |
876 | | |
877 | | bool HandleSource(cmSourceFile* sf, std::string const& propertyName, |
878 | | std::string const& propertyValue, bool appendAsString, |
879 | | bool appendMode, bool remove) |
880 | 0 | { |
881 | | // Special validation and handling of GENERATED flag? |
882 | 0 | if (propertyName == "GENERATED") { |
883 | 0 | SetPropertyCommand::PropertyOp op = (remove) |
884 | 0 | ? SetPropertyCommand::PropertyOp::Remove |
885 | 0 | : (appendAsString) ? SetPropertyCommand::PropertyOp::AppendAsString |
886 | 0 | : (appendMode) ? SetPropertyCommand::PropertyOp::Append |
887 | 0 | : SetPropertyCommand::PropertyOp::Set; |
888 | 0 | return SetPropertyCommand::HandleAndValidateSourceFilePropertyGENERATED( |
889 | 0 | sf, propertyValue, op); |
890 | 0 | } |
891 | | |
892 | | // Set or append the property. |
893 | 0 | if (appendMode) { |
894 | 0 | sf->AppendProperty(propertyName, propertyValue, appendAsString); |
895 | 0 | } else { |
896 | 0 | if (remove) { |
897 | 0 | sf->RemoveProperty(propertyName); |
898 | 0 | } else { |
899 | 0 | sf->SetProperty(propertyName, propertyValue); |
900 | 0 | } |
901 | 0 | } |
902 | 0 | return true; |
903 | 0 | } |
904 | | |
905 | | bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names, |
906 | | std::string const& propertyName, |
907 | | std::string const& propertyValue, bool appendAsString, |
908 | | bool appendMode, bool remove, cmMakefile* test_makefile) |
909 | 0 | { |
910 | | // Look for tests with all names given. |
911 | 0 | std::set<std::string>::iterator next; |
912 | 0 | for (auto ni = names.begin(); ni != names.end(); ni = next) { |
913 | 0 | next = ni; |
914 | 0 | ++next; |
915 | 0 | if (cmTest* test = test_makefile->GetTest(*ni)) { |
916 | 0 | if (HandleTest(test, propertyName, propertyValue, appendAsString, |
917 | 0 | appendMode, remove)) { |
918 | 0 | names.erase(ni); |
919 | 0 | } else { |
920 | 0 | return false; |
921 | 0 | } |
922 | 0 | } |
923 | 0 | } |
924 | | |
925 | | // Names that are still left were not found. |
926 | 0 | if (!names.empty()) { |
927 | 0 | status.SetError(cmStrCat("given TEST names that do not exist:\n", |
928 | 0 | cmWrap(" ", names, "\n", ""))); |
929 | 0 | return false; |
930 | 0 | } |
931 | 0 | return true; |
932 | 0 | } |
933 | | |
934 | | bool HandleTest(cmTest* test, std::string const& propertyName, |
935 | | std::string const& propertyValue, bool appendAsString, |
936 | | bool appendMode, bool remove) |
937 | 0 | { |
938 | | // Set or append the property. |
939 | 0 | if (appendMode) { |
940 | 0 | test->AppendProperty(propertyName, propertyValue, appendAsString); |
941 | 0 | } else { |
942 | 0 | if (remove) { |
943 | 0 | test->SetProperty(propertyName, nullptr); |
944 | 0 | } else { |
945 | 0 | test->SetProperty(propertyName, propertyValue); |
946 | 0 | } |
947 | 0 | } |
948 | |
|
949 | 0 | return true; |
950 | 0 | } |
951 | | |
952 | | bool HandleCacheMode(cmExecutionStatus& status, |
953 | | std::set<std::string> const& names, |
954 | | std::string const& propertyName, |
955 | | std::string const& propertyValue, bool appendAsString, |
956 | | bool appendMode, bool remove) |
957 | 0 | { |
958 | 0 | if (propertyName == "ADVANCED") { |
959 | 0 | if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) { |
960 | 0 | status.SetError(cmStrCat("given non-boolean value \"", propertyValue, |
961 | 0 | R"(" for CACHE property "ADVANCED". )")); |
962 | 0 | return false; |
963 | 0 | } |
964 | 0 | } else if (propertyName == "TYPE") { |
965 | 0 | if (!cmState::IsCacheEntryType(propertyValue)) { |
966 | 0 | status.SetError( |
967 | 0 | cmStrCat("given invalid CACHE entry TYPE \"", propertyValue, '"')); |
968 | 0 | return false; |
969 | 0 | } |
970 | 0 | } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" && |
971 | 0 | propertyName != "VALUE") { |
972 | 0 | status.SetError( |
973 | 0 | cmStrCat("given invalid CACHE property ", propertyName, |
974 | 0 | ". " |
975 | 0 | "Settable CACHE properties are: " |
976 | 0 | "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.")); |
977 | 0 | return false; |
978 | 0 | } |
979 | | |
980 | 0 | for (std::string const& name : names) { |
981 | | // Get the source file. |
982 | 0 | cmake* cm = status.GetMakefile().GetCMakeInstance(); |
983 | 0 | cmValue existingValue = cm->GetState()->GetCacheEntryValue(name); |
984 | 0 | if (existingValue) { |
985 | 0 | if (!HandleCacheEntry(name, status.GetMakefile(), propertyName, |
986 | 0 | propertyValue, appendAsString, appendMode, |
987 | 0 | remove)) { |
988 | 0 | return false; |
989 | 0 | } |
990 | 0 | } else { |
991 | 0 | status.SetError(cmStrCat("could not find CACHE variable ", name, |
992 | 0 | ". Perhaps it has not yet been created.")); |
993 | 0 | return false; |
994 | 0 | } |
995 | 0 | } |
996 | 0 | return true; |
997 | 0 | } |
998 | | |
999 | | bool HandleCacheEntry(std::string const& cacheKey, cmMakefile const& makefile, |
1000 | | std::string const& propertyName, |
1001 | | std::string const& propertyValue, bool appendAsString, |
1002 | | bool appendMode, bool remove) |
1003 | 0 | { |
1004 | | // Set or append the property. |
1005 | 0 | cmState* state = makefile.GetState(); |
1006 | 0 | if (remove) { |
1007 | 0 | state->RemoveCacheEntryProperty(cacheKey, propertyName); |
1008 | 0 | } |
1009 | 0 | if (appendMode) { |
1010 | 0 | state->AppendCacheEntryProperty(cacheKey, propertyName, propertyValue, |
1011 | 0 | appendAsString); |
1012 | 0 | } else { |
1013 | 0 | state->SetCacheEntryProperty(cacheKey, propertyName, propertyValue); |
1014 | 0 | } |
1015 | |
|
1016 | 0 | return true; |
1017 | 0 | } |
1018 | | |
1019 | | bool HandleInstallMode(cmExecutionStatus& status, |
1020 | | std::set<std::string> const& names, |
1021 | | std::string const& propertyName, |
1022 | | std::string const& propertyValue, bool appendAsString, |
1023 | | bool appendMode, bool remove) |
1024 | 0 | { |
1025 | 0 | cmake* cm = status.GetMakefile().GetCMakeInstance(); |
1026 | |
|
1027 | 0 | for (std::string const& name : names) { |
1028 | 0 | if (cmInstalledFile* file = |
1029 | 0 | cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) { |
1030 | 0 | if (!HandleInstall(file, status.GetMakefile(), propertyName, |
1031 | 0 | propertyValue, appendAsString, appendMode, remove)) { |
1032 | 0 | return false; |
1033 | 0 | } |
1034 | 0 | } else { |
1035 | 0 | status.SetError(cmStrCat( |
1036 | 0 | "given INSTALL name that could not be found or created: ", name)); |
1037 | 0 | return false; |
1038 | 0 | } |
1039 | 0 | } |
1040 | 0 | return true; |
1041 | 0 | } |
1042 | | |
1043 | | bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile, |
1044 | | std::string const& propertyName, |
1045 | | std::string const& propertyValue, bool appendAsString, |
1046 | | bool appendMode, bool remove) |
1047 | 0 | { |
1048 | | // Set or append the property. |
1049 | 0 | if (remove) { |
1050 | 0 | file->RemoveProperty(propertyName); |
1051 | 0 | } else if (appendMode) { |
1052 | 0 | file->AppendProperty(&makefile, propertyName, propertyValue, |
1053 | 0 | appendAsString); |
1054 | 0 | } else { |
1055 | 0 | file->SetProperty(&makefile, propertyName, propertyValue); |
1056 | 0 | } |
1057 | 0 | return true; |
1058 | 0 | } |
1059 | | } |