Browse Source

find_package: Use <PACKAGENAME>_ROOT variables as search prefixes

Extend commit eb35d8884b (find_package: Use PackageName_ROOT variables
as search prefixes, 2018-03-15, v3.12.0-rc1~349^2) to also check
upper-case `<PACKAGENAME>_ROOT` variables.  Add policy `CMP0144` to
enable the behavior in a compatible way.

Fixes: #24403
Brad King 2 years ago
parent
commit
df9c4b1872
27 changed files with 626 additions and 3 deletions
  1. 13 1
      Help/command/FIND_XXX.txt
  2. 13 1
      Help/command/find_package.rst
  3. 14 0
      Help/envvar/PackageName_ROOT.rst
  4. 8 0
      Help/manual/cmake-policies.7.rst
  5. 26 0
      Help/policy/CMP0144.rst
  6. 7 0
      Help/release/dev/find_package-PACKAGENAME_ROOT.rst
  7. 8 0
      Help/variable/PackageName_ROOT.rst
  8. 43 0
      Source/cmFindPackageCommand.cxx
  9. 21 0
      Source/cmMakefile.cxx
  10. 3 0
      Source/cmMakefile.h
  11. 4 1
      Source/cmPolicies.h
  12. 45 0
      Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt
  13. 3 0
      Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake
  14. 45 0
      Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt
  15. 3 0
      Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake
  16. 45 0
      Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt
  17. 3 0
      Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake
  18. 45 0
      Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt
  19. 3 0
      Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake
  20. 63 0
      Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt
  21. 3 0
      Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake
  22. 45 0
      Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt
  23. 3 0
      Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake
  24. 68 0
      Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt
  25. 3 0
      Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake
  26. 78 0
      Tests/RunCMake/find_package/CMP0144-common.cmake
  27. 11 0
      Tests/RunCMake/find_package/RunCMakeTest.cmake

+ 13 - 1
Help/command/FIND_XXX.txt

@@ -151,9 +151,21 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
    a. :variable:`<PackageName>_ROOT` CMake variable,
       where ``<PackageName>`` is the case-preserved package name.
 
-   b. :envvar:`<PackageName>_ROOT` environment variable,
+   b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
+   c. :envvar:`<PackageName>_ROOT` environment variable,
       where ``<PackageName>`` is the case-preserved package name.
 
+   d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
    The package root variables are maintained as a stack, so if called from
    nested find modules or config packages, root paths from the parent's find
    module or config package will be searched after paths from the current

+ 13 - 1
Help/command/find_package.rst

@@ -378,9 +378,21 @@ enabled.
    a. :variable:`<PackageName>_ROOT` CMake variable,
       where ``<PackageName>`` is the case-preserved package name.
 
-   b. :envvar:`<PackageName>_ROOT` environment variable,
+   b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
+   c. :envvar:`<PackageName>_ROOT` environment variable,
       where ``<PackageName>`` is the case-preserved package name.
 
+   d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
+      where ``<PACKAGENAME>`` is the upper-cased package name.
+      See policy :policy:`CMP0144`.
+
+      .. versionadded:: 3.27
+
    The package root variables are maintained as a stack so if
    called from within a find module, root paths from the parent's find
    module will also be searched after paths for the current package.

+ 14 - 0
Help/envvar/PackageName_ROOT.rst

@@ -17,3 +17,17 @@ by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
 variable convention on those platforms).
 
 See also the :variable:`<PackageName>_ROOT` CMake variable.
+
+.. envvar:: <PACKAGENAME>_ROOT
+
+  .. versionadded:: 3.27
+
+  Calls to :command:`find_package(<PackageName>)` will also search in
+  prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` environment
+  variable.  See policy :policy:`CMP0144`.
+
+.. note::
+
+  Note that the ``<PackageName>_ROOT`` and ``<PACKAGENAME>_ROOT``
+  environment variables are distinct only on platforms that have
+  case-sensitive environments.

+ 8 - 0
Help/manual/cmake-policies.7.rst

@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.27
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0144: find_package uses upper-case PACKAGENAME_ROOT variables. </policy/CMP0144>
+
 Policies Introduced by CMake 3.26
 =================================
 

+ 26 - 0
Help/policy/CMP0144.rst

@@ -0,0 +1,26 @@
+CMP0144
+-------
+
+.. versionadded:: 3.27
+
+:command:`find_package` uses upper-case ``<PACKAGENAME>_ROOT`` variables.
+
+In CMake 3.27 and above the :command:`find_package(<PackageName>)` command now
+searches prefixes specified by the upper-case :variable:`<PACKAGENAME>_ROOT`
+CMake variable and the :envvar:`<PACKAGENAME>_ROOT` environment variable
+in addition to the case-preserved :variable:`<PackageName>_ROOT` and
+:envvar:`<PackageName>_ROOT` variables used since policy :policy:`CMP0074`.
+This policy provides compatibility with projects that have not been
+updated to avoid using ``<PACKAGENAME>_ROOT`` variables for other purposes.
+
+The ``OLD`` behavior for this policy is to ignore ``<PACKAGENAME>_ROOT``
+variables if the original ``<PackageName>`` has lower-case characters.
+The ``NEW`` behavior for this policy is to use ``<PACKAGENAME>_ROOT``
+variables.
+
+This policy was introduced in CMake version 3.27.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt

+ 7 - 0
Help/release/dev/find_package-PACKAGENAME_ROOT.rst

@@ -0,0 +1,7 @@
+find_package-PACKAGENAME_ROOT
+-----------------------------
+
+* The :command:`find_package` command now searches prefixes specified by
+  upper-case :variable:`<PACKAGENAME>_ROOT` CMake variables and upper-case
+  :envvar:`<PACKAGENAME>_ROOT` environment variables.
+  See policy :policy:`CMP0144`.

+ 8 - 0
Help/variable/PackageName_ROOT.rst

@@ -14,3 +14,11 @@ This variable may hold a single prefix or a
 :ref:`semicolon-separated list <CMake Language Lists>` of multiple prefixes.
 
 See also the :envvar:`<PackageName>_ROOT` environment variable.
+
+.. variable:: <PACKAGENAME>_ROOT
+
+  .. versionadded:: 3.27
+
+  Calls to :command:`find_package(<PackageName>)` will also search in
+  prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` CMake
+  variable.  See policy :policy:`CMP0144`.

+ 43 - 0
Source/cmFindPackageCommand.cxx

@@ -1841,13 +1841,56 @@ void cmFindPackageCommand::PushFindPackageRootPathStack()
     } break;
   }
 
+  // Add root paths from <PACKAGENAME>_ROOT CMake and environment variables,
+  // if they are different than <PackageName>_ROOT, and subject to CMP0144.
+  std::string const rootVAR = cmSystemTools::UpperCase(rootVar);
+  cmValue rootDEF;
+  cm::optional<std::string> rootENV;
+  if (rootVAR != rootVar) {
+    rootDEF = this->Makefile->GetDefinition(rootVAR);
+    if (rootDEF && (rootDEF.IsEmpty() || rootDEF == rootDef)) {
+      rootDEF = nullptr;
+    }
+    rootENV = cmSystemTools::GetEnvVar(rootVAR);
+    if (rootENV && (rootENV->empty() || rootENV == rootEnv)) {
+      rootENV = cm::nullopt;
+    }
+  }
+
+  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0144)) {
+    case cmPolicies::WARN:
+      this->Makefile->MaybeWarnCMP0144(rootVAR, rootDEF, rootENV);
+      CM_FALLTHROUGH;
+    case cmPolicies::OLD:
+      // OLD behavior is to ignore the <PACKAGENAME>_ROOT variables.
+      rootDEF = nullptr;
+      rootENV = cm::nullopt;
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+      this->Makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0144));
+      return;
+    case cmPolicies::NEW: {
+      // NEW behavior is to honor the <PACKAGENAME>_ROOT variables.
+    } break;
+  }
+
   if (rootDef) {
     cmExpandList(*rootDef, rootPaths);
   }
+  if (rootDEF) {
+    cmExpandList(*rootDEF, rootPaths);
+  }
   if (rootEnv) {
     std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
     std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
   }
+  if (rootENV) {
+    std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootENV);
+    std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
+  }
 }
 
 void cmFindPackageCommand::PopFindPackageRootPathStack()

+ 21 - 0
Source/cmMakefile.cxx

@@ -228,6 +228,27 @@ void cmMakefile::MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
   }
 }
 
+void cmMakefile::MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
+                                  cm::optional<std::string> const& rootENV)
+{
+  // Warn if a <PACKAGENAME>_ROOT variable we may use is set.
+  if ((rootDEF || rootENV) && this->WarnedCMP0144.insert(rootVAR).second) {
+    std::ostringstream w;
+    w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0144) << "\n";
+    if (rootDEF) {
+      w << "CMake variable " << rootVAR << " is set to:\n"
+        << "  " << *rootDEF << "\n";
+    }
+    if (rootENV) {
+      w << "Environment variable " << rootVAR << " is set to:\n"
+        << "  " << *rootENV << "\n";
+    }
+    w << "For compatibility, find_package is ignoring the variable, but "
+         "code in a .cmake module might still use it.";
+    this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+  }
+}
+
 cmBTStringRange cmMakefile::GetIncludeDirectoriesEntries() const
 {
   return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();

+ 3 - 0
Source/cmMakefile.h

@@ -1013,6 +1013,8 @@ public:
 
   void MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef,
                         cm::optional<std::string> const& rootEnv);
+  void MaybeWarnCMP0144(std::string const& rootVAR, cmValue rootDEF,
+                        cm::optional<std::string> const& rootENV);
   void MaybeWarnUninitialized(std::string const& variable,
                               const char* sourceFilename) const;
   bool IsProjectFile(const char* filename) const;
@@ -1190,6 +1192,7 @@ private:
   bool CheckSystemVars;
   bool CheckCMP0000;
   std::set<std::string> WarnedCMP0074;
+  std::set<std::string> WarnedCMP0144;
   bool IsSourceFileTryCompile;
   mutable bool SuppressSideEffects;
   ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;

+ 4 - 1
Source/cmPolicies.h

@@ -434,7 +434,10 @@ class cmMakefile;
          3, 25, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0143,                                                     \
          "Global property USE_FOLDERS treated as ON by default", 3, 26, 0,    \
-         cmPolicies::WARN)
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0144,                                                     \
+         "find_package uses upper-case <PACKAGENAME>_ROOT variables.", 3, 27, \
+         0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \

+ 45 - 0
Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive-stderr.txt

@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-NEW-CaseInsensitive.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 NEW)
+include(CMP0144-common.cmake)

+ 45 - 0
Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive-stderr.txt

@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-NEW-CaseSensitive.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 NEW)
+include(CMP0144-common.cmake)

+ 45 - 0
Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive-stderr.txt

@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-OLD-CaseInsensitive.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 OLD)
+include(CMP0144-common.cmake)

+ 45 - 0
Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive-stderr.txt

@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-OLD-CaseSensitive.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+cmake_policy(SET CMP0144 OLD)
+include(CMP0144-common.cmake)

+ 63 - 0
Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive-stderr.txt

@@ -0,0 +1,63 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
++
+CMake Warning \(dev\) at CMP0144-common.cmake:[0-9]+ \(find_package\):
+  Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
+  variables.  Run "cmake --help-policy CMP0144" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+  CMake variable FOO_ROOT is set to:
+
+    [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+  For compatibility, find_package is ignoring the variable, but code in a
+  \.cmake module might still use it\.
+Call Stack \(most recent call first\):
+  CMP0144-common.cmake:[0-9]+ \(RunTestCase\)
+  CMP0144-WARN-CaseInsensitive.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-WARN-CaseInsensitive.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)

+ 45 - 0
Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed-stderr.txt

@@ -0,0 +1,45 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/cmake_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/cmake_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/cmake_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/cmake_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/cmake_root/bin/foo.exe
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: <base>/foo/env_root/include/foo.h
+FOO_TEST_FILE_ZOT: <base>/foo/env_root/include/zot/zot.h
+FOO_TEST_PATH_FOO: <base>/foo/env_root/include
+FOO_TEST_PATH_ZOT: <base>/foo/env_root/include/zot
+FOO_TEST_PROG_FOO: <base>/foo/env_root/bin/foo.exe
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-Mixed.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)

+ 68 - 0
Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive-stderr.txt

@@ -0,0 +1,68 @@
+^----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: '<base>/foo/env_root'
++
+CMake Warning \(dev\) at CMP0144-common.cmake:[0-9]+ \(find_package\):
+  Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
+  variables.  Run "cmake --help-policy CMP0144" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+  CMake variable FOO_ROOT is set to:
+
+    [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+  Environment variable FOO_ROOT is set to:
+
+    [^
+]*/Tests/RunCMake/find_package/PackageRoot/foo/env_root
+
+  For compatibility, find_package is ignoring the variable, but code in a
+  \.cmake module might still use it\.
+Call Stack \(most recent call first\):
+  CMP0144-common.cmake:[0-9]+ \(RunTestCase\)
+  CMP0144-WARN-CaseSensitive.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : '<base>/foo/cmake_root'
+ENV{FOO_ROOT}: ''
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
+FOO_ROOT     : ''
+ENV{FOO_ROOT}: '<base>/foo/env_root'
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO: FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT: FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO: FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT: FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO: FOO_TEST_PROG_FOO-NOTFOUND
+
+----------$

+ 3 - 0
Tests/RunCMake/find_package/CMP0144-WARN-CaseSensitive.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.26)
+# (do not set CMP0144)
+include(CMP0144-common.cmake)

+ 78 - 0
Tests/RunCMake/find_package/CMP0144-common.cmake

@@ -0,0 +1,78 @@
+# (includer selects CMP0144)
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+
+function(PrintPath label path)
+  string(REPLACE "${PackageRoot_BASE}" "<base>" out "${path}")
+  message("${label} ${out}")
+endfunction()
+
+macro(RunTestCase)
+  message("----------")
+  PrintPath("FOO_ROOT     :" "'${FOO_ROOT}'")
+  PrintPath("ENV{FOO_ROOT}:" "'$ENV{FOO_ROOT}'")
+  message("")
+
+  find_package(Foo)
+  message("find_package(Foo)")
+  PrintPath("FOO_TEST_FILE_FOO:" "${FOO_TEST_FILE_FOO}")
+  PrintPath("FOO_TEST_FILE_ZOT:" "${FOO_TEST_FILE_ZOT}")
+  PrintPath("FOO_TEST_PATH_FOO:" "${FOO_TEST_PATH_FOO}")
+  PrintPath("FOO_TEST_PATH_ZOT:" "${FOO_TEST_PATH_ZOT}")
+  PrintPath("FOO_TEST_PROG_FOO:" "${FOO_TEST_PROG_FOO}")
+  message("")
+
+  unset(FOO_ROOT)
+  unset(ENV{FOO_ROOT})
+  if(NOT CMAKE_HOST_WIN32)
+    unset(Foo_ROOT)
+    unset(ENV{Foo_ROOT})
+  endif()
+  unset(FOO_TEST_FILE_FOO)
+  unset(FOO_TEST_FILE_ZOT)
+  unset(FOO_TEST_PATH_FOO)
+  unset(FOO_TEST_PATH_ZOT)
+  unset(FOO_TEST_PROG_FOO)
+  unset(FOO_TEST_FILE_FOO CACHE)
+  unset(FOO_TEST_FILE_ZOT CACHE)
+  unset(FOO_TEST_PATH_FOO CACHE)
+  unset(FOO_TEST_PATH_ZOT CACHE)
+  unset(FOO_TEST_PROG_FOO CACHE)
+endmacro()
+
+RunTestCase()
+
+set(FOO_ROOT      ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{FOO_ROOT} ${PackageRoot_BASE}/foo/env_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+  if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+    set(Foo_ROOT      "${FOO_ROOT}")
+    set(ENV{Foo_ROOT} "$ENV{FOO_ROOT}")
+  else()
+    set(Foo_ROOT      ${PackageRoot_BASE}/does_not_exist)
+    set(ENV{Foo_ROOT} ${PackageRoot_BASE}/does_not_exist)
+  endif()
+endif()
+RunTestCase()
+
+set(FOO_ROOT      ${PackageRoot_BASE}/foo/cmake_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+  if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+    set(Foo_ROOT      "${FOO_ROOT}")
+  else()
+    set(Foo_ROOT      ${PackageRoot_BASE}/does_not_exist)
+  endif()
+endif()
+RunTestCase()
+
+set(ENV{FOO_ROOT} ${PackageRoot_BASE}/foo/env_root)
+if(RunCMake_TEST MATCHES "CaseSensitive")
+  if(RunCMake_TEST STREQUAL "CMP0144-WARN-CaseSensitive-Mixed")
+    set(ENV{Foo_ROOT} "$ENV{FOO_ROOT}")
+  else()
+    set(ENV{Foo_ROOT} ${PackageRoot_BASE}/does_not_exist)
+  endif()
+endif()
+RunTestCase()
+
+message("----------")

+ 11 - 0
Tests/RunCMake/find_package/RunCMakeTest.cmake

@@ -55,6 +55,17 @@ run_cmake(REGISTRY_VIEW-no-view)
 run_cmake(REGISTRY_VIEW-wrong-view)
 run_cmake(REGISTRY_VIEW-propagated)
 
+if(CMAKE_HOST_WIN32)
+  run_cmake(CMP0144-WARN-CaseInsensitive)
+  run_cmake(CMP0144-OLD-CaseInsensitive)
+  run_cmake(CMP0144-NEW-CaseInsensitive)
+else()
+  run_cmake(CMP0144-WARN-CaseSensitive)
+  run_cmake(CMP0144-WARN-CaseSensitive-Mixed)
+  run_cmake(CMP0144-OLD-CaseSensitive)
+  run_cmake(CMP0144-NEW-CaseSensitive)
+endif()
+
 file(
     GLOB SearchPaths_TEST_CASE_LIST
     LIST_DIRECTORIES TRUE