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,
    a. :variable:`<PackageName>_ROOT` CMake variable,
       where ``<PackageName>`` is the case-preserved package name.
       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.
       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
    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
    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
    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,
    a. :variable:`<PackageName>_ROOT` CMake variable,
       where ``<PackageName>`` is the case-preserved package name.
       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.
       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
    The package root variables are maintained as a stack so if
    called from within a find module, root paths from the parent's find
    called from within a find module, root paths from the parent's find
    module will also be searched after paths for the current package.
    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).
 variable convention on those platforms).
 
 
 See also the :variable:`<PackageName>_ROOT` CMake variable.
 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
 to determine whether to report an error on use of deprecated macros or
 functions.
 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
 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.
 :ref:`semicolon-separated list <CMake Language Lists>` of multiple prefixes.
 
 
 See also the :envvar:`<PackageName>_ROOT` environment variable.
 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;
     } 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) {
   if (rootDef) {
     cmExpandList(*rootDef, rootPaths);
     cmExpandList(*rootDef, rootPaths);
   }
   }
+  if (rootDEF) {
+    cmExpandList(*rootDEF, rootPaths);
+  }
   if (rootEnv) {
   if (rootEnv) {
     std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
     std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
     std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
     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()
 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
 cmBTStringRange cmMakefile::GetIncludeDirectoriesEntries() const
 {
 {
   return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
   return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();

+ 3 - 0
Source/cmMakefile.h

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

+ 4 - 1
Source/cmPolicies.h

@@ -434,7 +434,10 @@ class cmMakefile;
          3, 25, 0, cmPolicies::WARN)                                          \
          3, 25, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0143,                                                     \
   SELECT(POLICY, CMP0143,                                                     \
          "Global property USE_FOLDERS treated as ON by default", 3, 26, 0,    \
          "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_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
 #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-wrong-view)
 run_cmake(REGISTRY_VIEW-propagated)
 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(
 file(
     GLOB SearchPaths_TEST_CASE_LIST
     GLOB SearchPaths_TEST_CASE_LIST
     LIST_DIRECTORIES TRUE
     LIST_DIRECTORIES TRUE