/src/CMake/Source/cmOptionCommand.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 "cmOptionCommand.h" |
4 | | |
5 | | #include "cmExecutionStatus.h" |
6 | | #include "cmMakefile.h" |
7 | | #include "cmMessageType.h" |
8 | | #include "cmPolicies.h" |
9 | | #include "cmState.h" |
10 | | #include "cmStateSnapshot.h" |
11 | | #include "cmStateTypes.h" |
12 | | #include "cmStringAlgorithms.h" |
13 | | #include "cmValue.h" |
14 | | |
15 | | // cmOptionCommand |
16 | | bool cmOptionCommand(std::vector<std::string> const& args, |
17 | | cmExecutionStatus& status) |
18 | 0 | { |
19 | 0 | bool const argError = (args.size() < 2) || (args.size() > 3); |
20 | 0 | if (argError) { |
21 | 0 | std::string m = cmStrCat("called with incorrect number of arguments: ", |
22 | 0 | cmJoin(args, " ")); |
23 | 0 | status.SetError(m); |
24 | 0 | return false; |
25 | 0 | } |
26 | | |
27 | | // Determine the state of the option policy |
28 | 0 | bool checkAndWarn = false; |
29 | 0 | { |
30 | 0 | auto policyStatus = |
31 | 0 | status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077); |
32 | 0 | auto const& existsBeforeSet = |
33 | 0 | status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); |
34 | 0 | switch (policyStatus) { |
35 | 0 | case cmPolicies::WARN: |
36 | 0 | checkAndWarn = (existsBeforeSet != nullptr); |
37 | 0 | CM_FALLTHROUGH; |
38 | 0 | case cmPolicies::OLD: |
39 | | // OLD behavior does not warn. |
40 | 0 | break; |
41 | 0 | case cmPolicies::NEW: { |
42 | | // See if a local variable with this name already exists. |
43 | | // If so we ignore the option command. |
44 | 0 | if (existsBeforeSet) { |
45 | 0 | return true; |
46 | 0 | } |
47 | 0 | } break; |
48 | 0 | } |
49 | 0 | } |
50 | | |
51 | | // See if a cache variable with this name already exists |
52 | | // If so just make sure the doc state is correct |
53 | 0 | cmState* state = status.GetMakefile().GetState(); |
54 | 0 | cmValue existingValue = state->GetCacheEntryValue(args[0]); |
55 | 0 | if (existingValue && |
56 | 0 | (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) { |
57 | 0 | state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]); |
58 | 0 | return true; |
59 | 0 | } |
60 | | |
61 | | // Nothing in the cache so add it |
62 | 0 | std::string initialValue = existingValue ? *existingValue : "Off"; |
63 | 0 | if (args.size() == 3) { |
64 | 0 | initialValue = args[2]; |
65 | 0 | } |
66 | 0 | bool init = cmIsOn(initialValue); |
67 | 0 | status.GetMakefile().AddCacheDefinition(args[0], init ? "ON" : "OFF", |
68 | 0 | args[1], cmStateEnums::BOOL); |
69 | 0 | if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077) != |
70 | 0 | cmPolicies::NEW && |
71 | 0 | status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0126) == |
72 | 0 | cmPolicies::NEW) { |
73 | | // if there was a definition then remove it |
74 | 0 | status.GetMakefile().GetStateSnapshot().RemoveDefinition(args[0]); |
75 | 0 | } |
76 | |
|
77 | 0 | if (checkAndWarn) { |
78 | 0 | auto const& existsAfterSet = |
79 | 0 | status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]); |
80 | 0 | if (!existsAfterSet) { |
81 | 0 | status.GetMakefile().IssueMessage( |
82 | 0 | MessageType::AUTHOR_WARNING, |
83 | 0 | cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0077), |
84 | 0 | "\n" |
85 | 0 | "For compatibility with older versions of CMake, option " |
86 | 0 | "is clearing the normal variable '", |
87 | 0 | args[0], "'.")); |
88 | 0 | } |
89 | 0 | } |
90 | 0 | return true; |
91 | 0 | } |