Jelajahi Sumber

CMP0126: Add control for warnings

Fixes: #22353
Marc Chevrier 4 tahun lalu
induk
melakukan
16208ac113

+ 3 - 1
Help/policy/CMP0126.rst

@@ -15,6 +15,8 @@ behavior for this policy is to keep the normal variable of the same name.
 This policy was introduced in CMake version 3.21. Use the
 This policy was introduced in CMake version 3.21. Use the
 :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
 :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
 Unlike many policies, CMake version |release| does *not* warn when the policy
 Unlike many policies, CMake version |release| does *not* warn when the policy
-is not set and simply uses ``OLD`` behavior.
+is not set and simply uses ``OLD`` behavior.  See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0126 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
 
 
 .. include:: DEPRECATED.txt
 .. include:: DEPRECATED.txt

+ 2 - 0
Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst

@@ -29,6 +29,8 @@ warn by default:
   policy :policy:`CMP0112`.
   policy :policy:`CMP0112`.
 * ``CMAKE_POLICY_WARNING_CMP0116`` controls the warning for
 * ``CMAKE_POLICY_WARNING_CMP0116`` controls the warning for
   policy :policy:`CMP0116`.
   policy :policy:`CMP0116`.
+* ``CMAKE_POLICY_WARNING_CMP0126`` controls the warning for
+  policy :policy:`CMP0126`.
 
 
 This variable should not be set by a project in CMake code.  Project
 This variable should not be set by a project in CMake code.  Project
 developers running CMake may set this variable in their cache to
 developers running CMake may set this variable in their cache to

+ 20 - 3
Source/cmMakefile.cxx

@@ -1962,9 +1962,26 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
     }
     }
   }
   }
   this->GetCMakeInstance()->AddCacheEntry(name, value, doc, type);
   this->GetCMakeInstance()->AddCacheEntry(name, value, doc, type);
-  if (this->GetPolicyStatus(cmPolicies::CMP0126) != cmPolicies::NEW) {
-    // if there was a definition then remove it
-    this->StateSnapshot.RemoveDefinition(name);
+  switch (this->GetPolicyStatus(cmPolicies::CMP0126)) {
+    case cmPolicies::WARN:
+      if (this->PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0126") &&
+          this->IsNormalDefinitionSet(name)) {
+        this->IssueMessage(
+          MessageType::AUTHOR_WARNING,
+          cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0126),
+                   "\nFor compatibility with older versions of CMake, normal "
+                   "variable \"",
+                   name, "\" will be removed from the current scope."));
+      }
+      CM_FALLTHROUGH;
+    case cmPolicies::OLD:
+      // if there was a definition then remove it
+      this->StateSnapshot.RemoveDefinition(name);
+      break;
+    case cmPolicies::NEW:
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+      break;
   }
   }
 }
 }
 
 

+ 2 - 2
Source/cmProjectCommand.cxx

@@ -71,7 +71,7 @@ bool cmProjectCommand(std::vector<std::string> const& args,
   // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
   // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
   // will work.
   // will work.
   if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
   if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
-    mf.AddDefinition("CMAKE_PROJECT_NAME", projectName);
+    mf.RemoveDefinition("CMAKE_PROJECT_NAME");
     mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName,
     mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName,
                           "Value Computed by CMake", cmStateEnums::STATIC);
                           "Value Computed by CMake", cmStateEnums::STATIC);
   }
   }
@@ -395,7 +395,7 @@ static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
   // in the same CMakeLists.txt file, and it is the top level
   // in the same CMakeLists.txt file, and it is the top level
   // CMakeLists.txt file, then go with the last one.
   // CMakeLists.txt file, then go with the last one.
   if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
   if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
-    mf.AddDefinition(name, value);
+    mf.RemoveDefinition(name);
     mf.AddCacheDefinition(name, value, "Value Computed by CMake",
     mf.AddCacheDefinition(name, value, "Value Computed by CMake",
                           cmStateEnums::STATIC);
                           cmStateEnums::STATIC);
   }
   }

+ 3 - 0
Tests/RunCMake/CMP0126/CMP0126-WARN-default.cmake

@@ -0,0 +1,3 @@
+
+set(MY_VAR 1)
+set(MY_VAR 2 CACHE STRING "")

+ 10 - 0
Tests/RunCMake/CMP0126/CMP0126-WARN-stderr.txt

@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0126-WARN.cmake:[0-9]+ \(set\):
+  Policy CMP0126 is not set: set\(CACHE\) does not remove a normal variable of
+  the same name\.  Run "cmake --help-policy CMP0126" for policy details\.  Use
+  the cmake_policy command to set the policy and suppress this warning\.
+
+  For compatibility with older versions of CMake, normal variable "MY_VAR"
+  will be removed from the current scope\.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.

+ 5 - 0
Tests/RunCMake/CMP0126/CMP0126-WARN.cmake

@@ -0,0 +1,5 @@
+
+set(CMAKE_POLICY_WARNING_CMP0126 1)
+
+set(MY_VAR 1)
+set(MY_VAR 2 CACHE STRING "")

+ 2 - 0
Tests/RunCMake/CMP0126/RunCMakeTest.cmake

@@ -4,3 +4,5 @@ run_cmake(CMP0126-OLD)
 run_cmake_with_options(CMP0126-OLD_CL -DVAR=3)
 run_cmake_with_options(CMP0126-OLD_CL -DVAR=3)
 run_cmake(CMP0126-NEW)
 run_cmake(CMP0126-NEW)
 run_cmake_with_options(CMP0126-NEW_CL -DVAR=3)
 run_cmake_with_options(CMP0126-NEW_CL -DVAR=3)
+run_cmake(CMP0126-WARN)
+run_cmake(CMP0126-WARN-default)