浏览代码

Merge topic 'find_item-consistent-behavior-cache-variables'

08db1341a6 find_*: ensure consistent behavior for cache variables
f5fa6d53b0 class cmake: Store working directory at cmake launch
b1729200c3 find_*: refactor cache variable handling

Acked-by: Kitware Robot <[email protected]>
Merge-request: !6110
Brad King 4 年之前
父节点
当前提交
96011ab06d
共有 37 个文件被更改,包括 596 次插入112 次删除
  1. 1 0
      Help/manual/cmake-policies.7.rst
  2. 25 0
      Help/policy/CMP0125.rst
  3. 6 0
      Help/release/dev/find_item-consistent-behavior.rst
  4. 93 9
      Source/cmFindBase.cxx
  5. 9 1
      Source/cmFindBase.h
  6. 4 1
      Source/cmFindFileCommand.cxx
  7. 13 34
      Source/cmFindLibraryCommand.cxx
  8. 16 33
      Source/cmFindPathCommand.cxx
  9. 1 0
      Source/cmFindPathCommand.h
  10. 13 32
      Source/cmFindProgramCommand.cxx
  11. 2 0
      Source/cmMakefile.cxx
  12. 5 1
      Source/cmPolicies.h
  13. 2 1
      Source/cmake.cxx
  14. 9 0
      Source/cmake.h
  15. 51 0
      Tests/RunCMake/CMP0125/CMP0125-find_file-Common.cmake
  16. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_file-NEW-stderr.txt
  17. 4 0
      Tests/RunCMake/CMP0125/CMP0125-find_file-NEW.cmake
  18. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_file-OLD-stderr.txt
  19. 4 0
      Tests/RunCMake/CMP0125/CMP0125-find_file-OLD.cmake
  20. 52 0
      Tests/RunCMake/CMP0125/CMP0125-find_library-Common.cmake
  21. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_library-NEW-stderr.txt
  22. 6 0
      Tests/RunCMake/CMP0125/CMP0125-find_library-NEW.cmake
  23. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_library-OLD-stderr.txt
  24. 6 0
      Tests/RunCMake/CMP0125/CMP0125-find_library-OLD.cmake
  25. 51 0
      Tests/RunCMake/CMP0125/CMP0125-find_path-Common.cmake
  26. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_path-NEW-stderr.txt
  27. 4 0
      Tests/RunCMake/CMP0125/CMP0125-find_path-NEW.cmake
  28. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_path-OLD-stderr.txt
  29. 4 0
      Tests/RunCMake/CMP0125/CMP0125-find_path-OLD.cmake
  30. 52 0
      Tests/RunCMake/CMP0125/CMP0125-find_program-Common.cmake
  31. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_program-NEW-stderr.txt
  32. 4 0
      Tests/RunCMake/CMP0125/CMP0125-find_program-NEW.cmake
  33. 14 0
      Tests/RunCMake/CMP0125/CMP0125-find_program-OLD-stderr.txt
  34. 4 0
      Tests/RunCMake/CMP0125/CMP0125-find_program-OLD.cmake
  35. 3 0
      Tests/RunCMake/CMP0125/CMakeLists.txt
  36. 36 0
      Tests/RunCMake/CMP0125/RunCMakeTest.cmake
  37. 4 0
      Tests/RunCMake/CMakeLists.txt

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

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.21
 .. toctree::
 .. toctree::
    :maxdepth: 1
    :maxdepth: 1
 
 
+   CMP0125: find_(path|file|library|program) have consistent behavior for cache variables. </policy/CMP0125>
    CMP0124: foreach() loop variables are only available in the loop scope. </policy/CMP0124>
    CMP0124: foreach() loop variables are only available in the loop scope. </policy/CMP0124>
    CMP0123: ARMClang cpu/arch compile and link flags must be set explicitly. </policy/CMP0123>
    CMP0123: ARMClang cpu/arch compile and link flags must be set explicitly. </policy/CMP0123>
    CMP0122: UseSWIG use standard library name conventions for csharp language. </policy/CMP0122>
    CMP0122: UseSWIG use standard library name conventions for csharp language. </policy/CMP0122>

+ 25 - 0
Help/policy/CMP0125.rst

@@ -0,0 +1,25 @@
+CMP0125
+-------
+
+.. versionadded:: 3.21
+
+The :command:`find_file`, :command:`find_path`, :command:`find_library` and
+:command:`find_program` commands handle cache variables in the same way
+regardless of whether they are defined on the command line, with or without a
+type, or using the :command:`set` command.
+
+Starting with CMake 3.21, the :command:`find_file`, :command:`find_path`,
+:command:`find_library`, and :command:`find_program` commands ensure that the
+cache variables will be used in the same way regardless how they were defined
+and the result will be always successful if the searched artifact exists.
+
+The ``OLD`` behavior for this policy is to have the find commands' behaviors
+differ depending on how the cache variable is defined. The ``NEW`` behavior for
+this policy is to have consistent behavior.
+
+This policy was introduced in CMake version 3.21. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn when the policy
+is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt

+ 6 - 0
Help/release/dev/find_item-consistent-behavior.rst

@@ -0,0 +1,6 @@
+find_item-consistent-behavior
+-----------------------------
+
+* The :command:`find_file`, :command:`find_path`, :command:`find_program`,
+  and :command:`find_library` commands handle cache variables in the same way
+  regardless how they are defined. See policy :policy:`CMP0125` for details.

+ 93 - 9
Source/cmFindBase.cxx

@@ -9,7 +9,10 @@
 
 
 #include <cmext/algorithm>
 #include <cmext/algorithm>
 
 
+#include "cmCMakePath.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmProperty.h"
 #include "cmRange.h"
 #include "cmRange.h"
 #include "cmSearchPath.h"
 #include "cmSearchPath.h"
@@ -17,11 +20,13 @@
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
+#include "cmake.h"
 
 
 class cmExecutionStatus;
 class cmExecutionStatus;
 
 
-cmFindBase::cmFindBase(cmExecutionStatus& status)
+cmFindBase::cmFindBase(std::string findCommandName, cmExecutionStatus& status)
   : cmFindCommon(status)
   : cmFindCommon(status)
+  , FindCommandName(std::move(findCommandName))
 {
 {
 }
 }
 
 
@@ -299,27 +304,106 @@ bool cmFindBase::CheckForVariableInCache()
     cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName);
     cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName);
     bool found = !cmIsNOTFOUND(*cacheValue);
     bool found = !cmIsNOTFOUND(*cacheValue);
     bool cached = cacheEntry != nullptr;
     bool cached = cacheEntry != nullptr;
+    auto cacheType = cached ? state->GetCacheEntryType(this->VariableName)
+                            : cmStateEnums::UNINITIALIZED;
+
+    if (cached && cacheType != cmStateEnums::UNINITIALIZED) {
+      this->VariableType = cacheType;
+      if (const auto* hs =
+            state->GetCacheEntryProperty(this->VariableName, "HELPSTRING")) {
+        this->VariableDocumentation = *hs;
+      }
+    }
+
     if (found) {
     if (found) {
       // If the user specifies the entry on the command line without a
       // If the user specifies the entry on the command line without a
       // type we should add the type and docstring but keep the
       // type we should add the type and docstring but keep the
       // original value.  Tell the subclass implementations to do
       // original value.  Tell the subclass implementations to do
       // this.
       // this.
-      if (cached &&
-          state->GetCacheEntryType(this->VariableName) ==
-            cmStateEnums::UNINITIALIZED) {
+      if (cached && cacheType == cmStateEnums::UNINITIALIZED) {
         this->AlreadyInCacheWithoutMetaInfo = true;
         this->AlreadyInCacheWithoutMetaInfo = true;
       }
       }
       return true;
       return true;
     }
     }
-    if (cached) {
-      cmProp hs =
-        state->GetCacheEntryProperty(this->VariableName, "HELPSTRING");
-      this->VariableDocumentation = hs ? *hs : "(none)";
-    }
   }
   }
   return false;
   return false;
 }
 }
 
 
+void cmFindBase::NormalizeFindResult()
+{
+  if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) ==
+      cmPolicies::NEW) {
+    // ensure the path returned by find_* command is absolute
+    const auto* existingValue =
+      this->Makefile->GetDefinition(this->VariableName);
+    std::string value;
+    if (!existingValue->empty()) {
+      value =
+        cmCMakePath(*existingValue, cmCMakePath::auto_format)
+          .Absolute(cmCMakePath(
+            this->Makefile->GetCMakeInstance()->GetCMakeWorkingDirectory()))
+          .Normal()
+          .GenericString();
+      // value = cmSystemTools::CollapseFullPath(*existingValue);
+      if (!cmSystemTools::FileExists(value, false)) {
+        value = *existingValue;
+      }
+    }
+
+    // If the user specifies the entry on the command line without a
+    // type we should add the type and docstring but keep the original
+    // value.
+    if (value != *existingValue || this->AlreadyInCacheWithoutMetaInfo) {
+      this->Makefile->GetCMakeInstance()->AddCacheEntry(
+        this->VariableName, value.c_str(), this->VariableDocumentation.c_str(),
+        this->VariableType);
+      // if there was a definition then remove it
+      // This is required to ensure same behavior as
+      // cmMakefile::AddCacheDefinition.
+      // See #22038 for problems raised by this behavior.
+      this->Makefile->RemoveDefinition(this->VariableName);
+    }
+  } else {
+    // If the user specifies the entry on the command line without a
+    // type we should add the type and docstring but keep the original
+    // value.
+    if (this->AlreadyInCacheWithoutMetaInfo) {
+      this->Makefile->AddCacheDefinition(this->VariableName, "",
+                                         this->VariableDocumentation.c_str(),
+                                         this->VariableType);
+    }
+  }
+}
+
+void cmFindBase::StoreFindResult(const std::string& value)
+{
+  bool force =
+    this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) == cmPolicies::NEW;
+
+  if (!value.empty()) {
+    this->Makefile->AddCacheDefinition(this->VariableName, value,
+                                       this->VariableDocumentation.c_str(),
+                                       this->VariableType, force);
+    return;
+  }
+
+  this->Makefile->AddCacheDefinition(
+    this->VariableName, cmStrCat(this->VariableName, "-NOTFOUND"),
+    this->VariableDocumentation.c_str(), this->VariableType, force);
+
+  if (this->Required) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat("Could not find ", this->VariableName, " using the following ",
+               (this->FindCommandName == "find_file" ||
+                    this->FindCommandName == "find_path"
+                  ? "files"
+                  : "names"),
+               ": ", cmJoin(this->Names, ", ")));
+    cmSystemTools::SetFatalErrorOccured();
+  }
+}
+
 cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName,
 cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName,
                                            cmFindBase const* findBase)
                                            cmFindBase const* findBase)
   : FindCommand(findBase)
   : FindCommand(findBase)

+ 9 - 1
Source/cmFindBase.h

@@ -9,6 +9,7 @@
 #include <vector>
 #include <vector>
 
 
 #include "cmFindCommon.h"
 #include "cmFindCommon.h"
+#include "cmStateTypes.h"
 
 
 class cmExecutionStatus;
 class cmExecutionStatus;
 
 
@@ -21,7 +22,7 @@ class cmExecutionStatus;
 class cmFindBase : public cmFindCommon
 class cmFindBase : public cmFindCommon
 {
 {
 public:
 public:
-  cmFindBase(cmExecutionStatus& status);
+  cmFindBase(std::string findCommandName, cmExecutionStatus& status);
   virtual ~cmFindBase() = default;
   virtual ~cmFindBase() = default;
 
 
   /**
   /**
@@ -39,8 +40,15 @@ protected:
   // if it has documentation in the cache
   // if it has documentation in the cache
   bool CheckForVariableInCache();
   bool CheckForVariableInCache();
 
 
+  void NormalizeFindResult();
+  void StoreFindResult(const std::string& value);
+
+  // actual find command name
+  std::string FindCommandName;
+
   // use by command during find
   // use by command during find
   std::string VariableDocumentation;
   std::string VariableDocumentation;
+  cmStateEnums::CacheEntryType VariableType = cmStateEnums::UNINITIALIZED;
   std::string VariableName;
   std::string VariableName;
   std::vector<std::string> Names;
   std::vector<std::string> Names;
   bool NamesPerDir = false;
   bool NamesPerDir = false;

+ 4 - 1
Source/cmFindFileCommand.cxx

@@ -2,12 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmFindFileCommand.h"
 #include "cmFindFileCommand.h"
 
 
+#include "cmStateTypes.h"
+
 class cmExecutionStatus;
 class cmExecutionStatus;
 
 
 cmFindFileCommand::cmFindFileCommand(cmExecutionStatus& status)
 cmFindFileCommand::cmFindFileCommand(cmExecutionStatus& status)
-  : cmFindPathCommand(status)
+  : cmFindPathCommand("find_file", status)
 {
 {
   this->IncludeFileInPath = true;
   this->IncludeFileInPath = true;
+  this->VariableType = cmStateEnums::FILEPATH;
 }
 }
 
 
 bool cmFindFile(std::vector<std::string> const& args,
 bool cmFindFile(std::vector<std::string> const& args,

+ 13 - 34
Source/cmFindLibraryCommand.cxx

@@ -12,7 +12,6 @@
 
 
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
-#include "cmMessageType.h"
 #include "cmProperty.h"
 #include "cmProperty.h"
 #include "cmState.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
@@ -22,30 +21,26 @@
 class cmExecutionStatus;
 class cmExecutionStatus;
 
 
 cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
 cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
-  : cmFindBase(status)
+  : cmFindBase("find_library", status)
 {
 {
   this->EnvironmentPath = "LIB";
   this->EnvironmentPath = "LIB";
   this->NamesPerDirAllowed = true;
   this->NamesPerDirAllowed = true;
+  this->VariableDocumentation = "Path to a library.";
+  this->VariableType = cmStateEnums::FILEPATH;
 }
 }
 
 
 // cmFindLibraryCommand
 // cmFindLibraryCommand
 bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
 bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
 {
 {
   this->DebugMode = this->ComputeIfDebugModeWanted();
   this->DebugMode = this->ComputeIfDebugModeWanted();
-  this->VariableDocumentation = "Path to a library.";
   this->CMakePathName = "LIBRARY";
   this->CMakePathName = "LIBRARY";
+
   if (!this->ParseArguments(argsIn)) {
   if (!this->ParseArguments(argsIn)) {
     return false;
     return false;
   }
   }
+
   if (this->AlreadyInCache) {
   if (this->AlreadyInCache) {
-    // If the user specifies the entry on the command line without a
-    // type we should add the type and docstring but keep the original
-    // value.
-    if (this->AlreadyInCacheWithoutMetaInfo) {
-      this->Makefile->AddCacheDefinition(this->VariableName, "",
-                                         this->VariableDocumentation.c_str(),
-                                         cmStateEnums::FILEPATH);
-    }
+    this->NormalizeFindResult();
     return true;
     return true;
   }
   }
 
 
@@ -75,24 +70,7 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
   }
   }
 
 
   std::string const library = this->FindLibrary();
   std::string const library = this->FindLibrary();
-  if (!library.empty()) {
-    // Save the value in the cache
-    this->Makefile->AddCacheDefinition(this->VariableName, library,
-                                       this->VariableDocumentation.c_str(),
-                                       cmStateEnums::FILEPATH);
-    return true;
-  }
-  std::string notfound = this->VariableName + "-NOTFOUND";
-  this->Makefile->AddCacheDefinition(this->VariableName, notfound,
-                                     this->VariableDocumentation.c_str(),
-                                     cmStateEnums::FILEPATH);
-  if (this->Required) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "Could not find " + this->VariableName +
-        " using the following names: " + cmJoin(this->Names, ", "));
-    cmSystemTools::SetFatalErrorOccured();
-  }
+  this->StoreFindResult(library);
   return true;
   return true;
 }
 }
 
 
@@ -208,7 +186,8 @@ std::string cmFindLibraryCommand::FindLibrary()
 
 
 struct cmFindLibraryHelper
 struct cmFindLibraryHelper
 {
 {
-  cmFindLibraryHelper(cmMakefile* mf, cmFindBase const* findBase);
+  cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
+                      cmFindBase const* findBase);
 
 
   // Context information.
   // Context information.
   cmMakefile* Makefile;
   cmMakefile* Makefile;
@@ -280,11 +259,11 @@ struct cmFindLibraryHelper
   };
   };
 };
 };
 
 
-cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf,
+cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
                                          cmFindBase const* base)
                                          cmFindBase const* base)
   : Makefile(mf)
   : Makefile(mf)
   , DebugMode(base->DebugModeEnabled())
   , DebugMode(base->DebugModeEnabled())
-  , DebugSearches("find_library", base)
+  , DebugSearches(std::move(debugName), base)
 {
 {
   this->GG = this->Makefile->GetGlobalGenerator();
   this->GG = this->Makefile->GetGlobalGenerator();
 
 
@@ -485,7 +464,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
 std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
 std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
 {
 {
   // Search for all names in each directory.
   // Search for all names in each directory.
-  cmFindLibraryHelper helper(this->Makefile, this);
+  cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this);
   for (std::string const& n : this->Names) {
   for (std::string const& n : this->Names) {
     helper.AddName(n);
     helper.AddName(n);
   }
   }
@@ -502,7 +481,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
 std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
 std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
 {
 {
   // Search the entire path for each name.
   // Search the entire path for each name.
-  cmFindLibraryHelper helper(this->Makefile, this);
+  cmFindLibraryHelper helper(this->FindCommandName, this->Makefile, this);
   for (std::string const& n : this->Names) {
   for (std::string const& n : this->Names) {
     // Switch to searching for this name.
     // Switch to searching for this name.
     helper.SetName(n);
     helper.SetName(n);

+ 16 - 33
Source/cmFindPathCommand.cxx

@@ -2,70 +2,53 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmFindPathCommand.h"
 #include "cmFindPathCommand.h"
 
 
+#include <utility>
+
 #include "cmsys/Glob.hxx"
 #include "cmsys/Glob.hxx"
 
 
-#include "cmMakefile.h"
-#include "cmMessageType.h"
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 
 
 class cmExecutionStatus;
 class cmExecutionStatus;
 
 
-cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
-  : cmFindBase(status)
+cmFindPathCommand::cmFindPathCommand(std::string findCommandName,
+                                     cmExecutionStatus& status)
+  : cmFindBase(std::move(findCommandName), status)
 {
 {
   this->EnvironmentPath = "INCLUDE";
   this->EnvironmentPath = "INCLUDE";
   this->IncludeFileInPath = false;
   this->IncludeFileInPath = false;
+  this->VariableDocumentation = "Path to a file.";
+  this->VariableType = cmStateEnums::PATH;
+}
+cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
+  : cmFindPathCommand("find_path", status)
+{
 }
 }
 
 
 // cmFindPathCommand
 // cmFindPathCommand
 bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
 bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
 {
 {
   this->DebugMode = this->ComputeIfDebugModeWanted();
   this->DebugMode = this->ComputeIfDebugModeWanted();
-  this->VariableDocumentation = "Path to a file.";
   this->CMakePathName = "INCLUDE";
   this->CMakePathName = "INCLUDE";
+
   if (!this->ParseArguments(argsIn)) {
   if (!this->ParseArguments(argsIn)) {
     return false;
     return false;
   }
   }
+
   if (this->AlreadyInCache) {
   if (this->AlreadyInCache) {
-    // If the user specifies the entry on the command line without a
-    // type we should add the type and docstring but keep the original
-    // value.
-    if (this->AlreadyInCacheWithoutMetaInfo) {
-      this->Makefile->AddCacheDefinition(
-        this->VariableName, "", this->VariableDocumentation.c_str(),
-        (this->IncludeFileInPath ? cmStateEnums::FILEPATH
-                                 : cmStateEnums::PATH));
-    }
+    this->NormalizeFindResult();
     return true;
     return true;
   }
   }
 
 
   std::string result = this->FindHeader();
   std::string result = this->FindHeader();
-  if (!result.empty()) {
-    this->Makefile->AddCacheDefinition(
-      this->VariableName, result, this->VariableDocumentation.c_str(),
-      (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
-    return true;
-  }
-  this->Makefile->AddCacheDefinition(
-    this->VariableName, this->VariableName + "-NOTFOUND",
-    this->VariableDocumentation.c_str(),
-    (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
-  if (this->Required) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "Could not find " + this->VariableName +
-        " using the following files: " + cmJoin(this->Names, ", "));
-    cmSystemTools::SetFatalErrorOccured();
-  }
+  this->StoreFindResult(result);
   return true;
   return true;
 }
 }
 
 
 std::string cmFindPathCommand::FindHeader()
 std::string cmFindPathCommand::FindHeader()
 {
 {
-  std::string debug_name = this->IncludeFileInPath ? "find_file" : "find_path";
-  cmFindBaseDebugState debug(debug_name, this);
+  cmFindBaseDebugState debug(this->FindCommandName, this);
   std::string header;
   std::string header;
   if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) {
   if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) {
     header = this->FindFrameworkHeader(debug);
     header = this->FindFrameworkHeader(debug);

+ 1 - 0
Source/cmFindPathCommand.h

@@ -22,6 +22,7 @@ class cmFindPathCommand : public cmFindBase
 {
 {
 public:
 public:
   cmFindPathCommand(cmExecutionStatus& status);
   cmFindPathCommand(cmExecutionStatus& status);
+  cmFindPathCommand(std::string findCommandName, cmExecutionStatus& status);
 
 
   bool InitialPass(std::vector<std::string> const& args);
   bool InitialPass(std::vector<std::string> const& args);
 
 

+ 13 - 32
Source/cmFindProgramCommand.cxx

@@ -4,6 +4,7 @@
 
 
 #include <algorithm>
 #include <algorithm>
 #include <string>
 #include <string>
+#include <utility>
 
 
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmMessageType.h"
@@ -20,8 +21,9 @@ class cmExecutionStatus;
 
 
 struct cmFindProgramHelper
 struct cmFindProgramHelper
 {
 {
-  cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
-    : DebugSearches("find_program", base)
+  cmFindProgramHelper(std::string debugName, cmMakefile* makefile,
+                      cmFindBase const* base)
+    : DebugSearches(std::move(debugName), base)
     , Makefile(makefile)
     , Makefile(makefile)
     , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
     , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
   {
   {
@@ -145,52 +147,31 @@ struct cmFindProgramHelper
 };
 };
 
 
 cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
 cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
-  : cmFindBase(status)
+  : cmFindBase("find_program", status)
 {
 {
   this->NamesPerDirAllowed = true;
   this->NamesPerDirAllowed = true;
+  this->VariableDocumentation = "Path to a program.";
+  this->VariableType = cmStateEnums::FILEPATH;
 }
 }
 
 
 // cmFindProgramCommand
 // cmFindProgramCommand
 bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
 bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
 {
 {
   this->DebugMode = this->ComputeIfDebugModeWanted();
   this->DebugMode = this->ComputeIfDebugModeWanted();
-  this->VariableDocumentation = "Path to a program.";
   this->CMakePathName = "PROGRAM";
   this->CMakePathName = "PROGRAM";
+
   // call cmFindBase::ParseArguments
   // call cmFindBase::ParseArguments
   if (!this->ParseArguments(argsIn)) {
   if (!this->ParseArguments(argsIn)) {
     return false;
     return false;
   }
   }
+
   if (this->AlreadyInCache) {
   if (this->AlreadyInCache) {
-    // If the user specifies the entry on the command line without a
-    // type we should add the type and docstring but keep the original
-    // value.
-    if (this->AlreadyInCacheWithoutMetaInfo) {
-      this->Makefile->AddCacheDefinition(this->VariableName, "",
-                                         this->VariableDocumentation.c_str(),
-                                         cmStateEnums::FILEPATH);
-    }
+    this->NormalizeFindResult();
     return true;
     return true;
   }
   }
 
 
   std::string const result = this->FindProgram();
   std::string const result = this->FindProgram();
-  if (!result.empty()) {
-    // Save the value in the cache
-    this->Makefile->AddCacheDefinition(this->VariableName, result,
-                                       this->VariableDocumentation.c_str(),
-                                       cmStateEnums::FILEPATH);
-
-    return true;
-  }
-  this->Makefile->AddCacheDefinition(
-    this->VariableName, this->VariableName + "-NOTFOUND",
-    this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
-  if (this->Required) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "Could not find " + this->VariableName +
-        " using the following names: " + cmJoin(this->Names, ", "));
-    cmSystemTools::SetFatalErrorOccured();
-  }
+  this->StoreFindResult(result);
   return true;
   return true;
 }
 }
 
 
@@ -222,7 +203,7 @@ std::string cmFindProgramCommand::FindNormalProgram()
 std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
 std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
 {
 {
   // Search for all names in each directory.
   // Search for all names in each directory.
-  cmFindProgramHelper helper(this->Makefile, this);
+  cmFindProgramHelper helper(this->FindCommandName, this->Makefile, this);
   for (std::string const& n : this->Names) {
   for (std::string const& n : this->Names) {
     helper.AddName(n);
     helper.AddName(n);
   }
   }
@@ -245,7 +226,7 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
 std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
 std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
 {
 {
   // Search the entire path for each name.
   // Search the entire path for each name.
-  cmFindProgramHelper helper(this->Makefile, this);
+  cmFindProgramHelper helper(this->FindCommandName, this->Makefile, this);
   for (std::string const& n : this->Names) {
   for (std::string const& n : this->Names) {
     // Switch to searching for this name.
     // Switch to searching for this name.
     helper.SetName(n);
     helper.SetName(n);

+ 2 - 0
Source/cmMakefile.cxx

@@ -1963,6 +1963,8 @@ 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 there was a definition then remove it
   // if there was a definition then remove it
+  // The method cmFindBase::NormalizeFindResult also apply same workflow.
+  // See #22038 for problems raised by this behavior.
   this->StateSnapshot.RemoveDefinition(name);
   this->StateSnapshot.RemoveDefinition(name);
 }
 }
 
 

+ 5 - 1
Source/cmPolicies.h

@@ -372,7 +372,11 @@ class cmMakefile;
          3, 21, 0, cmPolicies::WARN)                                          \
          3, 21, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0124,                                                     \
   SELECT(POLICY, CMP0124,                                                     \
          "foreach() loop variables are only available in the loop scope.", 3, \
          "foreach() loop variables are only available in the loop scope.", 3, \
-         21, 0, cmPolicies::WARN)
+         21, 0, cmPolicies::WARN)                                             \
+  SELECT(POLICY, CMP0125,                                                     \
+         "find_(path|file|library|program) have consistent behavior for "     \
+         "cache variables.",                                                  \
+         3, 21, 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)                                         \

+ 2 - 1
Source/cmake.cxx

@@ -157,7 +157,8 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
 #endif
 #endif
 
 
 cmake::cmake(Role role, cmState::Mode mode)
 cmake::cmake(Role role, cmState::Mode mode)
-  : FileTimeCache(cm::make_unique<cmFileTimeCache>())
+  : CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory())
+  , FileTimeCache(cm::make_unique<cmFileTimeCache>())
 #ifndef CMAKE_BOOTSTRAP
 #ifndef CMAKE_BOOTSTRAP
   , VariableWatch(cm::make_unique<cmVariableWatch>())
   , VariableWatch(cm::make_unique<cmVariableWatch>())
 #endif
 #endif

+ 9 - 0
Source/cmake.h

@@ -193,6 +193,14 @@ public:
   std::string const& GetHomeOutputDirectory() const;
   std::string const& GetHomeOutputDirectory() const;
   //@}
   //@}
 
 
+  /**
+   * Working directory at CMake launch
+   */
+  std::string const& GetCMakeWorkingDirectory() const
+  {
+    return this->CMakeWorkingDirectory;
+  }
+
   /**
   /**
    * Handle a command line invocation of cmake.
    * Handle a command line invocation of cmake.
    */
    */
@@ -628,6 +636,7 @@ protected:
   void GenerateGraphViz(const std::string& fileName) const;
   void GenerateGraphViz(const std::string& fileName) const;
 
 
 private:
 private:
+  std::string CMakeWorkingDirectory;
   ProgressCallbackType ProgressCallback;
   ProgressCallbackType ProgressCallback;
   WorkingMode CurrentWorkingMode = NORMAL_MODE;
   WorkingMode CurrentWorkingMode = NORMAL_MODE;
   bool DebugOutput = false;
   bool DebugOutput = false;

+ 51 - 0
Tests/RunCMake/CMP0125/CMP0125-find_file-Common.cmake

@@ -0,0 +1,51 @@
+
+find_file(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_file(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_file(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "")
+find_file(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH=${RELATIVE_PATH}")
+message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}")
+
+message("ABSOLUTE_PATH=${ABSOLUTE_PATH}")
+message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}")
+
+message("NOTFOUND_PATH=${NOTFOUND_PATH}")
+message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}")
+
+message("FILE_NAME=${FILE_NAME}")
+message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}")
+
+
+set(RELATIVE_PATH_AND_LOCAL relative_local)
+set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local)
+set(ABSOLUTE_PATH_AND_LOCAL /absolute_local)
+set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local)
+set(NOTFOUND_AND_LOCAL "${FILE_NAME}")
+set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}")
+
+find_file(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_file(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_file(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_file(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}")
+message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}")
+message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}")
+message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}")

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_file-NEW-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=/.+/CMP0125/file\.txt
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt
+FILE_NAME=/.+/CMP0125/CMP0125-find_file-NEW-build/file2\.txt
+FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_file-NEW-build/file2\.txt
+RELATIVE_PATH_AND_LOCAL=relative_local
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute_local
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/file.txt
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file.txt

+ 4 - 0
Tests/RunCMake/CMP0125/CMP0125-find_file-NEW.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0125 NEW)
+
+include(CMP0125-find_file-Common.cmake)

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_file-OLD-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=/.+/CMP0125/CMP0125-find_file-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt
+FILE_NAME=/.+/CMP0125/CMP0125-find_file-OLD-build/file2\.txt
+FILE_NAME_WITH_TYPE=file2\.txt
+RELATIVE_PATH_AND_LOCAL=/.+/CMP0125/CMP0125-find_file-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file\.txt

+ 4 - 0
Tests/RunCMake/CMP0125/CMP0125-find_file-OLD.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0125 OLD)
+
+include(CMP0125-find_file-Common.cmake)

+ 52 - 0
Tests/RunCMake/CMP0125/CMP0125-find_library-Common.cmake

@@ -0,0 +1,52 @@
+
+find_library(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_library(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_library(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "")
+file(CHMOD "${CMAKE_BINARY_DIR}/${FILE_NAME}" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE)
+find_library(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH=${RELATIVE_PATH}")
+message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}")
+
+message("ABSOLUTE_PATH=${ABSOLUTE_PATH}")
+message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}")
+
+message("NOTFOUND_PATH=${NOTFOUND_PATH}")
+message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}")
+
+message("FILE_NAME=${FILE_NAME}")
+message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}")
+
+
+set(RELATIVE_PATH_AND_LOCAL relative_local)
+set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local)
+set(ABSOLUTE_PATH_AND_LOCAL /absolute_local)
+set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local)
+set(NOTFOUND_AND_LOCAL "${FILE_NAME}")
+set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}")
+
+find_library(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_library(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_library(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_library(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}")
+message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}")
+message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}")
+message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}")

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_library-NEW-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=/.+/CMP0125/libfile\.(so|dylib)
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/libfile\.(so|dylib)
+FILE_NAME=/.+/CMP0125/CMP0125-find_library-NEW-build/libfile2\.(so|dylib)
+FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_library-NEW-build/libfile2\.(so|dylib)
+RELATIVE_PATH_AND_LOCAL=relative_local
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute_local
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/libfile.(so|dylib)
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/libfile.(so|dylib)

+ 6 - 0
Tests/RunCMake/CMP0125/CMP0125-find_library-NEW.cmake

@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0125 NEW)
+
+enable_language(C)
+
+include(CMP0125-find_library-Common.cmake)

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_library-OLD-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=/.+/CMP0125/CMP0125-find_library-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/libfile\.(so|dylib)
+FILE_NAME=/.+/CMP0125/CMP0125-find_library-OLD-build/libfile2\.(so|dylib)
+FILE_NAME_WITH_TYPE=libfile2\.(so|dylib)
+RELATIVE_PATH_AND_LOCAL=relative_local
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute_local
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/libfile\.(so|dylib)
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/libfile\.(so|dylib)

+ 6 - 0
Tests/RunCMake/CMP0125/CMP0125-find_library-OLD.cmake

@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0125 OLD)
+
+enable_language(C)
+
+include(CMP0125-find_library-Common.cmake)

+ 51 - 0
Tests/RunCMake/CMP0125/CMP0125-find_path-Common.cmake

@@ -0,0 +1,51 @@
+
+find_path(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_path(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_path(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "")
+find_path(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH=${RELATIVE_PATH}")
+message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}")
+
+message("ABSOLUTE_PATH=${ABSOLUTE_PATH}")
+message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}")
+
+message("NOTFOUND_PATH=${NOTFOUND_PATH}")
+message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}")
+
+message("FILE_NAME=${FILE_NAME}")
+message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}")
+
+
+set(RELATIVE_PATH_AND_LOCAL relative_local)
+set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local)
+set(ABSOLUTE_PATH_AND_LOCAL /absolute_local)
+set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local)
+set(NOTFOUND_AND_LOCAL "${FILE_NAME}")
+set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}")
+
+find_path(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_path(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_path(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_path(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}")
+message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}")
+message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}")
+message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}")

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_path-NEW-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=/.+/CMP0125
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125
+FILE_NAME=/.+/CMP0125/CMP0125-find_path-NEW-build/file2\.txt
+FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_path-NEW-build/file2\.txt
+RELATIVE_PATH_AND_LOCAL=relative_local
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute_local
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125

+ 4 - 0
Tests/RunCMake/CMP0125/CMP0125-find_path-NEW.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0125 NEW)
+
+include(CMP0125-find_path-Common.cmake)

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_path-OLD-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=/.+/CMP0125/CMP0125-find_path-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125
+FILE_NAME=/.+/CMP0125/CMP0125-find_path-OLD-build/file2\.txt
+FILE_NAME_WITH_TYPE=file2\.txt
+RELATIVE_PATH_AND_LOCAL=/.+/CMP0125/CMP0125-find_path-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125

+ 4 - 0
Tests/RunCMake/CMP0125/CMP0125-find_path-OLD.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0125 OLD)
+
+include(CMP0125-find_path-Common.cmake)

+ 52 - 0
Tests/RunCMake/CMP0125/CMP0125-find_program-Common.cmake

@@ -0,0 +1,52 @@
+
+find_program(RELATIVE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(RELATIVE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_program(ABSOLUTE_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(ABSOLUTE_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_program(NOTFOUND_PATH NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(NOTFOUND_PATH_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+file(WRITE "${CMAKE_BINARY_DIR}/${FILE_NAME}" "")
+file(CHMOD "${CMAKE_BINARY_DIR}/${FILE_NAME}" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE)
+find_program(FILE_NAME NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(FILE_NAME_WITH_TYPE NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH=${RELATIVE_PATH}")
+message("RELATIVE_PATH_WITH_TYPE=${RELATIVE_PATH_WITH_TYPE}")
+
+message("ABSOLUTE_PATH=${ABSOLUTE_PATH}")
+message("ABSOLUTE_PATH_WITH_TYPE=${ABSOLUTE_PATH_WITH_TYPE}")
+
+message("NOTFOUND_PATH=${NOTFOUND_PATH}")
+message("NOTFOUND_PATH_WITH_TYPE=${NOTFOUND_PATH_WITH_TYPE}")
+
+message("FILE_NAME=${FILE_NAME}")
+message("FILE_NAME_WITH_TYPE=${FILE_NAME_WITH_TYPE}")
+
+
+set(RELATIVE_PATH_AND_LOCAL relative_local)
+set(RELATIVE_PATH_WITH_TYPE_AND_LOCAL relative_local)
+set(ABSOLUTE_PATH_AND_LOCAL /absolute_local)
+set(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL /absolute_local)
+set(NOTFOUND_AND_LOCAL "${FILE_NAME}")
+set(NOTFOUND_WITH_TYPE_AND_LOCAL "${FILE_NAME}")
+
+find_program(RELATIVE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(RELATIVE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_program(ABSOLUTE_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+find_program(NOTFOUND_PATH_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+find_program(NOTFOUND_PATH_WITH_TYPE_AND_LOCAL NAMES ${SEARCH_NAME} PATHS ${SEARCH_PATH})
+
+message("RELATIVE_PATH_AND_LOCAL=${RELATIVE_PATH_AND_LOCAL}")
+message("RELATIVE_PATH_WITH_TYPE_AND_LOCAL=${RELATIVE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("ABSOLUTE_PATH_AND_LOCAL=${ABSOLUTE_PATH_AND_LOCAL}")
+message("ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=${ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL}")
+
+message("NOTFOUND_PATH_AND_LOCAL=${NOTFOUND_PATH_AND_LOCAL}")
+message("NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=${NOTFOUND_PATH_WITH_TYPE_AND_LOCAL}")

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_program-NEW-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=/.+/CMP0125/file\.txt
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt
+FILE_NAME=/.+/CMP0125/CMP0125-find_program-NEW-build/file2\.txt
+FILE_NAME_WITH_TYPE=/.+/CMP0125/CMP0125-find_program-NEW-build/file2\.txt
+RELATIVE_PATH_AND_LOCAL=relative_local
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute_local
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=/.+/CMP0125/file.txt
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file.txt

+ 4 - 0
Tests/RunCMake/CMP0125/CMP0125-find_program-NEW.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0125 NEW)
+
+include(CMP0125-find_program-Common.cmake)

+ 14 - 0
Tests/RunCMake/CMP0125/CMP0125-find_program-OLD-stderr.txt

@@ -0,0 +1,14 @@
+RELATIVE_PATH=/.+/CMP0125/CMP0125-find_program-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE=relative
+ABSOLUTE_PATH=/absolute
+ABSOLUTE_PATH_WITH_TYPE=/absolute
+NOTFOUND_PATH=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE=/.+/CMP0125/file\.txt
+FILE_NAME=/.+/CMP0125/CMP0125-find_program-OLD-build/file2\.txt
+FILE_NAME_WITH_TYPE=file2\.txt
+RELATIVE_PATH_AND_LOCAL=/.+/CMP0125/CMP0125-find_program-OLD-build/relative
+RELATIVE_PATH_WITH_TYPE_AND_LOCAL=relative_local
+ABSOLUTE_PATH_AND_LOCAL=/absolute
+ABSOLUTE_PATH_WITH_TYPE_AND_LOCAL=/absolute_local
+NOTFOUND_PATH_AND_LOCAL=NOTFOUND
+NOTFOUND_PATH_WITH_TYPE_AND_LOCAL=/.+/CMP0125/file.txt

+ 4 - 0
Tests/RunCMake/CMP0125/CMP0125-find_program-OLD.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0125 OLD)
+
+include(CMP0125-find_program-Common.cmake)

+ 3 - 0
Tests/RunCMake/CMP0125/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.20)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 36 - 0
Tests/RunCMake/CMP0125/RunCMakeTest.cmake

@@ -0,0 +1,36 @@
+include(RunCMake)
+
+file(WRITE "${RunCMake_BINARY_DIR}/file.txt" "")
+file(CHMOD "${RunCMake_BINARY_DIR}/file.txt" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE)
+
+set(options -DRELATIVE_PATH=relative -DABSOLUTE_PATH=/absolute
+  -DRELATIVE_PATH_WITH_TYPE:PATH=relative -DABSOLUTE_PATH_WITH_TYPE:PATH=/absolute
+  -DNOTFOUND_PATH=NOTFOUND -DNOTFOUND_PATH_WITH_TYPE:PATH=NOTFOUND
+  -DFILE_NAME=file2.txt -DFILE_NAME_WITH_TYPE:PATH=file2.txt
+  -DSEARCH_NAME=file.txt "-DSEARCH_PATH=${RunCMake_BINARY_DIR}"
+  -DRELATIVE_PATH_AND_LOCAL=relative -DABSOLUTE_PATH_AND_LOCAL=/absolute
+  -DRELATIVE_PATH_WITH_TYPE_AND_LOCAL:PATH=relative -DABSOLUTE_PATH_WITH_TYPE_AND_LOCAL:PATH=/absolute
+  -DNOTFOUND_PATH_AND_LOCAL=NOTFOUND -DNOTFOUND_PATH_WITH_TYPE_AND_LOCAL:PATH=NOTFOUND
+  -DFILE_NAME=file2.txt -DFILE_NAME_WITH_TYPE:PATH=file2.txt
+  -DSEARCH_NAME=file.txt "-DSEARCH_PATH=${RunCMake_BINARY_DIR}")
+
+run_cmake_with_options(CMP0125-find_file-OLD ${options})
+run_cmake_with_options(CMP0125-find_file-NEW ${options})
+run_cmake_with_options(CMP0125-find_path-OLD ${options})
+run_cmake_with_options(CMP0125-find_path-NEW ${options})
+run_cmake_with_options(CMP0125-find_program-OLD ${options})
+run_cmake_with_options(CMP0125-find_program-NEW ${options})
+
+
+file(WRITE "${RunCMake_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}file${CMAKE_SHARED_LIBRARY_SUFFIX}" "")
+file(CHMOD "${RunCMake_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}file${CMAKE_SHARED_LIBRARY_SUFFIX}" PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE)
+
+set(options -DRELATIVE_PATH=relative -DABSOLUTE_PATH=/absolute
+  -DRELATIVE_PATH_WITH_TYPE:PATH=relative -DABSOLUTE_PATH_WITH_TYPE:PATH=/absolute
+  -DNOTFOUND_PATH=NOTFOUND -DNOTFOUND_PATH_WITH_TYPE:PATH=NOTFOUND
+  -DFILE_NAME=${CMAKE_SHARED_LIBRARY_PREFIX}file2${CMAKE_SHARED_LIBRARY_SUFFIX}
+  -DFILE_NAME_WITH_TYPE:PATH=${CMAKE_SHARED_LIBRARY_PREFIX}file2${CMAKE_SHARED_LIBRARY_SUFFIX}
+  -DSEARCH_NAME=file "-DSEARCH_PATH=${RunCMake_BINARY_DIR}")
+
+run_cmake_with_options(CMP0125-find_library-OLD ${options})
+run_cmake_with_options(CMP0125-find_library-NEW ${options})

+ 4 - 0
Tests/RunCMake/CMakeLists.txt

@@ -136,6 +136,10 @@ endif()
 add_RunCMake_test(CMP0118)
 add_RunCMake_test(CMP0118)
 add_RunCMake_test(CMP0119 -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
 add_RunCMake_test(CMP0119 -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
 add_RunCMake_test(CMP0121)
 add_RunCMake_test(CMP0121)
+if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)")
+  add_RunCMake_test(CMP0125 -DCMAKE_SHARED_LIBRARY_PREFIX=${CMAKE_SHARED_LIBRARY_PREFIX}
+                            -DCMAKE_SHARED_LIBRARY_SUFFIX=${CMAKE_SHARED_LIBRARY_SUFFIX})
+endif()
 
 
 # The test for Policy 65 requires the use of the
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode