Deprecate compatibility with CMake versions older than 2.8.12

Issue a deprecation warning on calls to `cmake_minimum_required` or
`cmake_policy` that set policies based on versions older than 2.8.12.
Note that the effective policy version includes `...<max>` treatment.
This is important in combination with commit ca24b70d31 (Export: Specify
a policy range in exported files, 2020-05-16, v3.18.0-rc1~133^2).
diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst
index f92aea7..1dc01cc 100644
--- a/Help/release/dev/deprecate-policy-old.rst
+++ b/Help/release/dev/deprecate-policy-old.rst
@@ -6,3 +6,8 @@
   The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
   of all policies are deprecated and that projects should port to the
   NEW behaviors.
+
+* Compatibility with versions of CMake older than 2.8.12 is now deprecated
+  and will be removed from a future version.  Calls to
+  :command:`cmake_minimum_required` or :command:`cmake_policy` that set
+  the policy version to an older value now issue a deprecation diagnostic.
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3c1cba2..891e290 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1659,7 +1659,8 @@
         this->SetCheckCMP0000(true);
 
         // Implicitly set the version for the user.
-        this->SetPolicyVersion("2.4", std::string());
+        cmPolicies::ApplyPolicyVersion(this, 2, 4, 0,
+                                       cmPolicies::WarnCompat::Off);
       }
     }
     bool hasProject = false;
@@ -4621,7 +4622,8 @@
 bool cmMakefile::SetPolicyVersion(std::string const& version_min,
                                   std::string const& version_max)
 {
-  return cmPolicies::ApplyPolicyVersion(this, version_min, version_max);
+  return cmPolicies::ApplyPolicyVersion(this, version_min, version_max,
+                                        cmPolicies::WarnCompat::On);
 }
 
 bool cmMakefile::HasCMP0054AlreadyBeenReported(
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index dea3f8a..01e8c04 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -7,9 +7,11 @@
 #include <sstream>
 #include <vector>
 
+#include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmState.h"
+#include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -157,7 +159,8 @@
 
 bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
                                     std::string const& version_min,
-                                    std::string const& version_max)
+                                    std::string const& version_max,
+                                    WarnCompat warnCompat)
 {
   // Parse components of the minimum version.
   unsigned int minMajor = 2;
@@ -244,13 +247,34 @@
     polPatch = maxPatch;
   }
 
-  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch);
+  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch,
+                                        warnCompat);
 }
 
 bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
                                     unsigned int minorVer,
-                                    unsigned int patchVer)
+                                    unsigned int patchVer,
+                                    WarnCompat warnCompat)
 {
+  // Warn about policy versions for which support will be removed.
+  if (warnCompat == WarnCompat::On &&
+      (majorVer < 2 || (majorVer == 2 && minorVer < 8) ||
+       (majorVer == 2 && minorVer == 8 && patchVer < 12)) &&
+      // Avoid warning on calls generated by install(EXPORT)
+      // in CMake versions prior to 3.18.
+      !(majorVer == 2 && minorVer == 6 && patchVer == 0 &&
+        mf->GetStateSnapshot().CanPopPolicyScope() &&
+        cmSystemTools::Strucmp(mf->GetBacktrace().Top().Name.c_str(),
+                               "cmake_policy") == 0)) {
+    mf->IssueMessage(
+      MessageType::DEPRECATION_WARNING,
+      "Compatibility with CMake < 2.8.12 will be removed from "
+      "a future version of CMake.\n"
+      "Update the VERSION argument <min> value or use a ...<max> suffix "
+      "to tell CMake that the project does not need compatibility with "
+      "older versions.");
+  }
+
   // now loop over all the policies and set them as appropriate
   std::vector<cmPolicies::PolicyID> ancientPolicies;
   for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 49dadc7..bba8b03 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -399,12 +399,20 @@
   //! Get the default status for a policy
   static cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
 
+  enum class WarnCompat
+  {
+    Off,
+    On
+  };
+
   //! Set a policy level for this listfile
   static bool ApplyPolicyVersion(cmMakefile* mf,
                                  std::string const& version_min,
-                                 std::string const& version_max);
+                                 std::string const& version_max,
+                                 WarnCompat warnCompat);
   static bool ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
-                                 unsigned int minorVer, unsigned int patchVer);
+                                 unsigned int minorVer, unsigned int patchVer,
+                                 WarnCompat warnCompat);
 
   //! return a warning string for a given policy
   static std::string GetPolicyWarning(cmPolicies::PolicyID id);
diff --git a/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
index 048762d..a446211 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Deprecation Warning at CMP0019-OLD.cmake:[0-9]+ \(cmake_policy\):
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
+CMake Deprecation Warning at CMP0019-OLD.cmake:[0-9]+ \(cmake_policy\):
   The OLD behavior for policy CMP0019 will be removed from a future version
   of CMake.
 
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
index 1e4b47d..f7b9c0e 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
@@ -1,3 +1,10 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
 CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0019 is not set: Do not re-expand variables in include and link
   information.  Run "cmake --help-policy CMP0019" for policy details.  Use
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
index 6a6a0c7..87404d3 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
@@ -1,3 +1,10 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
 CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
   interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
index 2f7dfbf..5d75720 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Warning \(dev\) in CMakeLists.txt:
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
+CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
   interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
   cmake_policy command to set the policy and suppress this warning.
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt b/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt
new file mode 100644
index 0000000..7d40dcb
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt
@@ -0,0 +1,26 @@
+^CMake Deprecation Warning at Before2812.cmake:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Deprecation Warning at Before2812.cmake:2 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Deprecation Warning at Before2812.cmake:6 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/Before2812.cmake b/Tests/RunCMake/cmake_minimum_required/Before2812.cmake
new file mode 100644
index 0000000..220e359
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before2812.cmake
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.11)
+cmake_policy(VERSION 2.6)
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6) # simulate pre-3.18 install(EXPORT)-generated call
+cmake_policy(POP)
+cmake_policy(VERSION 2.8.11)
diff --git a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
index 4b3de84..667561e 100644
--- a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
+++ b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
@@ -1,3 +1,3 @@
 cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
index a874466..81d26d2 100644
--- a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
+++ b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
@@ -1,3 +1,12 @@
+^CMake Deprecation Warning at CompatBefore24.cmake:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
 CMake Error in CMakeLists.txt:
   You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less than
   2.4.  This version of CMake only supports backwards compatibility with
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
index 1030211..3a959bb 100644
--- a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -4,6 +4,7 @@
 run_cmake(CompatBefore24)
 run_cmake(Future)
 run_cmake(PolicyBefore24)
+run_cmake(Before2812)
 run_cmake(Range)
 run_cmake(RangeBad)
 run_cmake(Unknown)
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
index a0f8837..9103bd2 100644
--- a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
@@ -1,4 +1,13 @@
-^CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
+^CMake Deprecation Warning at GET-CMP0007-WARN.cmake:1 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
   Policy CMP0007 is not set: list command no longer ignores empty elements.
   Run "cmake --help-policy CMP0007" for policy details.  Use the cmake_policy
   command to set the policy and suppress this warning.  List has value =