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