Browse Source

Merge topic 'normalize-input-paths'

ee83165923 cmake: Explicitly normalize input paths as they exist on disk
9d44a77454 find_*: Explicitly normalize found paths as they exist on disk
967d3ea85c cmake-gui: Explicitly normalize input paths as they exist on disk
074ad98ebc ctest: Explicitly normalize input paths as they exist on disk
1f14238701 cpack: Explicitly normalize input paths as they exist on disk
9fe09ebc53 cmSystemTools: Add GetEnvPathNormalized to get paths from environment
2108f3507f cmSystemTools: Add SplitEnvPathNormalized to split paths from environment
6d57403e14 cmSystemTools: Fix SplitEnvPath to avoid empty paths
...

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !9929
Brad King 1 year ago
parent
commit
063e98eb4b
35 changed files with 252 additions and 246 deletions
  1. 2 2
      Source/CPack/cpack.cxx
  2. 3 5
      Source/CTest/cmCTestBuildHandler.cxx
  3. 1 1
      Source/CTest/cmCTestGIT.cxx
  4. 3 1
      Source/CTest/cmCTestRunScriptCommand.cxx
  5. 2 3
      Source/CTest/cmCTestScriptHandler.cxx
  6. 2 2
      Source/CTest/cmCTestTestHandler.cxx
  7. 6 6
      Source/QtDialog/CMakeSetup.cxx
  8. 1 3
      Source/QtDialog/QCMake.cxx
  9. 13 11
      Source/cmCTest.cxx
  10. 8 5
      Source/cmFindBase.cxx
  11. 16 23
      Source/cmFindLibraryCommand.cxx
  12. 7 5
      Source/cmFindPackageCommand.cxx
  13. 1 1
      Source/cmFindPathCommand.cxx
  14. 14 19
      Source/cmFindProgramCommand.cxx
  15. 1 1
      Source/cmLocalGenerator.cxx
  16. 1 1
      Source/cmMakefile.cxx
  17. 2 5
      Source/cmMakefileTargetGenerator.cxx
  18. 0 1
      Source/cmQtAutoGenerator.cxx
  19. 26 30
      Source/cmSearchPath.cxx
  20. 2 4
      Source/cmSearchPath.h
  21. 6 11
      Source/cmStateDirectory.cxx
  22. 44 5
      Source/cmSystemTools.cxx
  23. 6 1
      Source/cmSystemTools.h
  24. 35 45
      Source/cmake.cxx
  25. 1 7
      Source/cmake.h
  26. 3 3
      Source/cmakemain.cxx
  27. 9 9
      Source/cmcmd.cxx
  28. 8 8
      Tests/FindPackageTest/CMakeLists.txt
  29. 22 22
      Tests/RunCMake/CXXModules/check-json.cmake
  30. 1 1
      Tests/RunCMake/CommandLine/C_basic-stdout.txt
  31. 2 1
      Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt
  32. 2 2
      Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt
  33. 0 0
      Tests/RunCMake/VS10Project/CSharpSourceGroup/Images/empty.bmp
  34. 1 1
      Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
  35. 1 1
      Tests/RunCMake/get_filename_component/KnownComponents.cmake

+ 2 - 2
Source/CPack/cpack.cxx

@@ -406,7 +406,7 @@ int main(int argc, char const* const* argv)
 
   bool cpackConfigFileSpecified = true;
   if (!cpackConfigFile.empty()) {
-    cpackConfigFile = cmSystemTools::CollapseFullPath(cpackConfigFile);
+    cpackConfigFile = cmSystemTools::ToNormalizedPathOnDisk(cpackConfigFile);
   } else {
     cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(),
                                "/CPackConfig.cmake");
@@ -480,7 +480,7 @@ int main(int argc, char const* const* argv)
     if (!cpackProjectDirectory.empty()) {
       // The value has been set on the command line.  Ensure it is absolute.
       cpackProjectDirectory =
-        cmSystemTools::CollapseFullPath(cpackProjectDirectory);
+        cmSystemTools::ToNormalizedPathOnDisk(cpackProjectDirectory);
     } else {
       // The value has not been set on the command line.  Check config file.
       if (cmValue pd = globalMF.GetDefinition("CPACK_PACKAGE_DIRECTORY")) {

+ 3 - 5
Source/CTest/cmCTestBuildHandler.cxx

@@ -580,9 +580,6 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml)
   int numErrorsAllowed = this->MaxErrors;
   int numWarningsAllowed = this->MaxWarnings;
   std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory");
-  // make sure the source dir is in the correct case on windows
-  // via a call to collapse full path.
-  srcdir = cmStrCat(cmSystemTools::CollapseFullPath(srcdir), '/');
   for (it = ew.begin();
        it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++) {
     cmCTestBuildErrorWarning* cm = &(*it);
@@ -613,8 +610,9 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml)
             }
           } else {
             // make sure it is a full path with the correct case
-            cm->SourceFile = cmSystemTools::CollapseFullPath(cm->SourceFile);
-            cmSystemTools::ReplaceString(cm->SourceFile, srcdir.c_str(), "");
+            cm->SourceFile =
+              cmSystemTools::ToNormalizedPathOnDisk(cm->SourceFile);
+            cmSystemTools::ReplaceString(cm->SourceFile, srcdir, "");
           }
           cm->LineNumber = atoi(re->match(rit.LineIndex).c_str());
           break;

+ 1 - 1
Source/CTest/cmCTestGIT.cxx

@@ -146,7 +146,7 @@ std::string cmCTestGIT::FindTopDir()
       !cdup.empty()) {
     top_dir += "/";
     top_dir += cdup;
-    top_dir = cmSystemTools::CollapseFullPath(top_dir);
+    top_dir = cmSystemTools::ToNormalizedPathOnDisk(top_dir);
   }
   return top_dir;
 }

+ 3 - 1
Source/CTest/cmCTestRunScriptCommand.cxx

@@ -5,6 +5,7 @@
 #include "cmCTestScriptHandler.h"
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmSystemTools.h"
 
 bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
                                           cmExecutionStatus& status)
@@ -36,7 +37,8 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args,
       ++i;
     } else {
       int ret;
-      cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i],
+      cmCTestScriptHandler::RunScript(this->CTest, this->Makefile,
+                                      cmSystemTools::CollapseFullPath(args[i]),
                                       !np, &ret);
       this->Makefile->AddDefinition(returnVariable, std::to_string(ret));
     }

+ 2 - 3
Source/CTest/cmCTestScriptHandler.cxx

@@ -74,9 +74,8 @@ int cmCTestScriptHandler::ProcessHandler()
   int res = 0;
   for (size_t i = 0; i < this->ConfigurationScripts.size(); ++i) {
     // for each script run it
-    res |= this->RunConfigurationScript(
-      cmSystemTools::CollapseFullPath(this->ConfigurationScripts[i]),
-      this->ScriptProcessScope[i]);
+    res |= this->RunConfigurationScript(this->ConfigurationScripts[i],
+                                        this->ScriptProcessScope[i]);
   }
   if (res) {
     return -1;

+ 2 - 2
Source/CTest/cmCTestTestHandler.cxx

@@ -1786,7 +1786,7 @@ std::string cmCTestTestHandler::FindExecutable(
   for (unsigned int ai = 0; ai < attempted.size() && fullPath.empty(); ++ai) {
     // first check without exe extension
     if (cmSystemTools::FileExists(attempted[ai], true)) {
-      fullPath = cmSystemTools::CollapseFullPath(attempted[ai]);
+      fullPath = cmSystemTools::ToNormalizedPathOnDisk(attempted[ai]);
       resultingConfig = attemptedConfigs[ai];
     }
     // then try with the exe extension
@@ -1795,7 +1795,7 @@ std::string cmCTestTestHandler::FindExecutable(
       tempPath =
         cmStrCat(attempted[ai], cmSystemTools::GetExecutableExtension());
       if (cmSystemTools::FileExists(tempPath, true)) {
-        fullPath = cmSystemTools::CollapseFullPath(tempPath);
+        fullPath = cmSystemTools::ToNormalizedPathOnDisk(tempPath);
         resultingConfig = attemptedConfigs[ai];
       } else {
         failed.push_back(tempPath);

+ 6 - 6
Source/QtDialog/CMakeSetup.cxx

@@ -172,8 +172,8 @@ int main(int argc, char** argv)
         }
       }
 
-      sourceDirectory = cmSystemTools::CollapseFullPath(path.toStdString());
-      cmSystemTools::ConvertToUnixSlashes(sourceDirectory);
+      sourceDirectory =
+        cmSystemTools::ToNormalizedPathOnDisk(path.toStdString());
     } else if (arg.startsWith("-B")) {
       QString path = arg.mid(2);
       if (path.isEmpty()) {
@@ -189,8 +189,8 @@ int main(int argc, char** argv)
         }
       }
 
-      binaryDirectory = cmSystemTools::CollapseFullPath(path.toStdString());
-      cmSystemTools::ConvertToUnixSlashes(binaryDirectory);
+      binaryDirectory =
+        cmSystemTools::ToNormalizedPathOnDisk(path.toStdString());
     } else if (arg.startsWith("--preset=")) {
       QString preset = arg.mid(cmStrLen("--preset="));
       if (preset.isEmpty()) {
@@ -223,7 +223,7 @@ int main(int argc, char** argv)
   } else {
     if (args.count() == 2) {
       std::string filePath =
-        cmSystemTools::CollapseFullPath(args[1].toStdString());
+        cmSystemTools::ToNormalizedPathOnDisk(args[1].toStdString());
 
       // check if argument is a directory containing CMakeCache.txt
       std::string buildFilePath = cmStrCat(filePath, "/CMakeCache.txt");
@@ -243,7 +243,7 @@ int main(int argc, char** argv)
       } else if (cmSystemTools::FileExists(srcFilePath.c_str())) {
         dialog.setSourceDirectory(QString::fromStdString(filePath));
         dialog.setBinaryDirectory(
-          QString::fromStdString(cmSystemTools::CollapseFullPath(".")));
+          QString::fromStdString(cmSystemTools::GetCurrentWorkingDirectory()));
       }
     }
   }

+ 1 - 3
Source/QtDialog/QCMake.cxx

@@ -258,9 +258,7 @@ void QCMake::configure()
 #endif
     // Apply the same transformations that the command-line invocation does
     auto sanitizePath = [](QString const& value) -> std::string {
-      std::string path = cmSystemTools::CollapseFullPath(value.toStdString());
-      cmSystemTools::ConvertToUnixSlashes(path);
-      return path;
+      return cmSystemTools::ToNormalizedPathOnDisk(value.toStdString());
     };
 
     this->CMakeInstance->SetHomeDirectory(sanitizePath(this->SourceDirectory));

+ 13 - 11
Source/cmCTest.cxx

@@ -818,7 +818,7 @@ int cmCTest::ProcessSteps()
   const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
   std::string workDir = currDir;
   if (!this->Impl->TestDir.empty()) {
-    workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir);
+    workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir);
   }
 
   cmWorkingDirectory changeDir(workDir);
@@ -2104,21 +2104,24 @@ int cmCTest::Run(std::vector<std::string> const& args)
     [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool {
     // -SR is an internal argument, -SP should be ignored when it is passed
     if (!SRArgumentSpecified) {
-      runScripts.emplace_back(script, false);
+      runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script),
+                              false);
     }
     return true;
   };
   auto const dashSR =
     [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool {
     SRArgumentSpecified = true;
-    runScripts.emplace_back(script, true);
+    runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script),
+                            true);
     return true;
   };
   auto const dash_S =
     [&runScripts, &SRArgumentSpecified](std::string const& script) -> bool {
     // -SR is an internal argument, -S should be ignored when it is passed
     if (!SRArgumentSpecified) {
-      runScripts.emplace_back(script, true);
+      runScripts.emplace_back(cmSystemTools::ToNormalizedPathOnDisk(script),
+                              true);
     }
     return true;
   };
@@ -2274,9 +2277,9 @@ int cmCTest::Run(std::vector<std::string> const& args)
           return false;
         }
         this->Impl->BuildAndTest.SourceDir =
-          cmSystemTools::CollapseFullPath(dirList[0]);
+          cmSystemTools::ToNormalizedPathOnDisk(dirList[0]);
         this->Impl->BuildAndTest.BinaryDir =
-          cmSystemTools::CollapseFullPath(dirList[1]);
+          cmSystemTools::ToNormalizedPathOnDisk(dirList[1]);
         cmSystemTools::MakeDirectory(this->Impl->BuildAndTest.BinaryDir);
         return true;
       } },
@@ -2847,7 +2850,7 @@ int cmCTest::ExecuteTests()
   const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
   std::string workDir = currDir;
   if (!this->Impl->TestDir.empty()) {
-    workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir);
+    workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir);
   }
 
   cmWorkingDirectory changeDir(workDir);
@@ -3039,10 +3042,9 @@ void cmCTest::PopulateCustomInteger(cmMakefile* mf, const std::string& def,
 
 std::string cmCTest::GetShortPathToFile(const std::string& cfname)
 {
-  const std::string& sourceDir = cmSystemTools::CollapseFullPath(
-    this->GetCTestConfiguration("SourceDirectory"));
-  const std::string& buildDir = cmSystemTools::CollapseFullPath(
-    this->GetCTestConfiguration("BuildDirectory"));
+  const std::string& sourceDir =
+    this->GetCTestConfiguration("SourceDirectory");
+  const std::string& buildDir = this->GetCTestConfiguration("BuildDirectory");
   std::string fname = cmSystemTools::CollapseFullPath(cfname);
 
   // Find relative paths to both directories

+ 8 - 5
Source/cmFindBase.cxx

@@ -56,7 +56,9 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
       } else if (argsIn[j] == "ENV") {
         if (j + 1 < size) {
           j++;
-          cmSystemTools::GetPath(args, argsIn[j].c_str());
+          std::vector<std::string> p =
+            cmSystemTools::GetEnvPathNormalized(argsIn[j]);
+          std::move(p.begin(), p.end(), std::back_inserter(args));
         }
       } else {
         args.push_back(argsIn[j]);
@@ -403,9 +405,11 @@ void cmFindBase::FillCMakeSystemVariablePath()
     cmList expanded{ *prefix_paths };
     install_entry.remove_self(expanded);
     staging_entry.remove_self(expanded);
-
-    paths.AddPrefixPaths(expanded,
-                         this->Makefile->GetCurrentSourceDirectory().c_str());
+    for (std::string& p : expanded) {
+      p = cmSystemTools::CollapseFullPath(
+        p, this->Makefile->GetCurrentSourceDirectory());
+    }
+    paths.AddPrefixPaths(expanded);
   } else if (add_install_prefix && !install_prefix_in_list) {
     paths.AddCMakePrefixPath("CMAKE_INSTALL_PREFIX");
     paths.AddCMakePrefixPath("CMAKE_STAGING_PREFIX");
@@ -493,7 +497,6 @@ void cmFindBase::NormalizeFindResult()
             this->Makefile->GetCMakeInstance()->GetCMakeWorkingDirectory()))
           .Normal()
           .GenericString();
-      // value = cmSystemTools::CollapseFullPath(*existingValue);
       if (!cmSystemTools::FileExists(value, false)) {
         value = *existingValue;
       }

+ 16 - 23
Source/cmFindLibraryCommand.cxx

@@ -220,9 +220,6 @@ struct cmFindLibraryHelper
   };
   std::vector<Name> Names;
 
-  // Current full path under consideration.
-  std::string TestPath;
-
   void RegexFromLiteral(std::string& out, std::string const& in);
   void RegexFromList(std::string& out, cmList const& in);
   size_type GetPrefixIndex(std::string const& prefix)
@@ -423,20 +420,17 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
   // one cannot tell just from the library name whether it is a static
   // library or an import library).
   if (name.TryRaw) {
-    this->TestPath = cmStrCat(path, name.Raw);
+    std::string testPath = cmStrCat(path, name.Raw);
 
-    const bool exists = cmSystemTools::FileExists(this->TestPath, true);
-    if (!exists) {
-      this->DebugLibraryFailed(name.Raw, path);
-    } else {
-      auto testPath = cmSystemTools::CollapseFullPath(this->TestPath);
+    if (cmSystemTools::FileExists(testPath, true)) {
+      testPath = cmSystemTools::ToNormalizedPathOnDisk(testPath);
       if (this->Validate(testPath)) {
         this->DebugLibraryFound(name.Raw, path);
         this->BestPath = testPath;
         return true;
       }
-      this->DebugLibraryFailed(name.Raw, path);
     }
+    this->DebugLibraryFailed(name.Raw, path);
   }
 
   // No library file has yet been found.
@@ -446,9 +440,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
   unsigned int bestMinor = 0;
 
   // Search for a file matching the library name regex.
-  std::string dir = path;
-  cmSystemTools::ConvertToUnixSlashes(dir);
-  std::set<std::string> const& files = this->GG->GetDirectoryContent(dir);
+  std::set<std::string> const& files = this->GG->GetDirectoryContent(path);
   for (std::string const& origName : files) {
 #if defined(_WIN32) || defined(__APPLE__)
     std::string testName = cmSystemTools::LowerCase(origName);
@@ -456,14 +448,15 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
     std::string const& testName = origName;
 #endif
     if (name.Regex.find(testName)) {
-      this->TestPath = cmStrCat(path, origName);
+      std::string testPath = cmStrCat(path, origName);
       // Make sure the path is readable and is not a directory.
-      if (cmSystemTools::FileExists(this->TestPath, true)) {
-        if (!this->Validate(cmSystemTools::CollapseFullPath(this->TestPath))) {
+      if (cmSystemTools::FileExists(testPath, true)) {
+        testPath = cmSystemTools::ToNormalizedPathOnDisk(testPath);
+        if (!this->Validate(testPath)) {
           continue;
         }
 
-        this->DebugLibraryFound(name.Raw, dir);
+        this->DebugLibraryFound(name.Raw, path);
         // This is a matching file.  Check if it is better than the
         // best name found so far.  Earlier prefixes are preferred,
         // followed by earlier suffixes.  For OpenBSD, shared library
@@ -480,7 +473,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
             (prefix == bestPrefix && suffix == bestSuffix &&
              (major > bestMajor ||
               (major == bestMajor && minor > bestMinor)))) {
-          this->BestPath = this->TestPath;
+          this->BestPath = testPath;
           bestPrefix = prefix;
           bestSuffix = suffix;
           bestMajor = major;
@@ -491,7 +484,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
   }
 
   if (this->BestPath.empty()) {
-    this->DebugLibraryFailed(name.Raw, dir);
+    this->DebugLibraryFailed(name.Raw, path);
   } else {
     this->DebugLibraryFound(name.Raw, this->BestPath);
   }
@@ -560,7 +553,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
     for (std::string const& n : this->Names) {
       fwPath = cmStrCat(d, n, ".xcframework");
       if (cmSystemTools::FileIsDirectory(fwPath)) {
-        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+        auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
         if (this->Validate(finalPath)) {
           return finalPath;
         }
@@ -568,7 +561,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
 
       fwPath = cmStrCat(d, n, ".framework");
       if (cmSystemTools::FileIsDirectory(fwPath)) {
-        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+        auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
         if (this->Validate(finalPath)) {
           return finalPath;
         }
@@ -588,7 +581,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
     for (std::string const& d : this->SearchPaths) {
       fwPath = cmStrCat(d, n, ".xcframework");
       if (cmSystemTools::FileIsDirectory(fwPath)) {
-        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+        auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
         if (this->Validate(finalPath)) {
           return finalPath;
         }
@@ -596,7 +589,7 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
 
       fwPath = cmStrCat(d, n, ".framework");
       if (cmSystemTools::FileIsDirectory(fwPath)) {
-        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+        auto finalPath = cmSystemTools::ToNormalizedPathOnDisk(fwPath);
         if (this->Validate(finalPath)) {
           return finalPath;
         }

+ 7 - 5
Source/cmFindPackageCommand.cxx

@@ -1961,11 +1961,13 @@ void cmFindPackageCommand::PushFindPackageRootPathStack()
     cmExpandList(*rootDEF, rootPaths);
   }
   if (rootEnv) {
-    std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootEnv);
+    std::vector<std::string> p =
+      cmSystemTools::SplitEnvPathNormalized(*rootEnv);
     std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
   }
   if (rootENV) {
-    std::vector<std::string> p = cmSystemTools::SplitEnvPath(*rootENV);
+    std::vector<std::string> p =
+      cmSystemTools::SplitEnvPathNormalized(*rootENV);
     std::move(p.begin(), p.end(), std::back_inserter(rootPaths));
   }
 }
@@ -2116,9 +2118,9 @@ void cmFindPackageCommand::FillPrefixesSystemEnvironment()
   // Use the system search path to generate prefixes.
   // Relative paths are interpreted with respect to the current
   // working directory.
-  std::vector<std::string> tmp;
-  cmSystemTools::GetPath(tmp);
-  for (std::string const& i : tmp) {
+  std::vector<std::string> envPATH =
+    cmSystemTools::GetEnvPathNormalized("PATH");
+  for (std::string const& i : envPATH) {
     // If the path is a PREFIX/bin case then add its parent instead.
     if ((cmHasLiteralSuffix(i, "/bin")) || (cmHasLiteralSuffix(i, "/sbin"))) {
       paths.AddPath(cmSystemTools::GetFilenamePath(i));

+ 1 - 1
Source/cmFindPathCommand.cxx

@@ -106,7 +106,7 @@ std::string cmFindPathCommand::FindHeaderInFramework(
   globIt.FindFiles(glob);
   std::vector<std::string> files = globIt.GetFiles();
   if (!files.empty()) {
-    std::string fheader = cmSystemTools::CollapseFullPath(files[0]);
+    std::string fheader = cmSystemTools::ToNormalizedPathOnDisk(files[0]);
     debug.FoundAt(fheader);
     if (this->IncludeFileInPath) {
       return fheader;

+ 14 - 19
Source/cmFindProgramCommand.cxx

@@ -48,12 +48,6 @@ struct cmFindProgramHelper
   // Current names under consideration.
   std::vector<std::string> Names;
 
-  // Current name with extension under consideration.
-  std::string TestNameExt;
-
-  // Current full path under consideration.
-  std::string TestPath;
-
   // Debug state
   cmFindBaseDebugState DebugSearches;
   cmMakefile* Makefile;
@@ -81,8 +75,6 @@ struct cmFindProgramHelper
   {
     return std::any_of(this->Names.begin(), this->Names.end(),
                        [this, &path](std::string const& n) -> bool {
-                         // Only perform search relative to current directory
-                         // if the file name contains a directory separator.
                          return this->CheckDirectoryForName(path, n);
                        });
   }
@@ -93,20 +85,23 @@ struct cmFindProgramHelper
                          if (!ext.empty() && cmHasSuffix(name, ext)) {
                            return false;
                          }
-                         this->TestNameExt = cmStrCat(name, ext);
-                         this->TestPath = cmSystemTools::CollapseFullPath(
-                           this->TestNameExt, path);
-                         bool exists = this->FileIsValid(this->TestPath);
-                         exists ? this->DebugSearches.FoundAt(this->TestPath)
-                                : this->DebugSearches.FailedAt(this->TestPath);
-                         if (exists) {
-                           this->BestPath = this->TestPath;
-                           return true;
+                         std::string testNameExt = cmStrCat(name, ext);
+                         std::string testPath =
+                           cmSystemTools::CollapseFullPath(testNameExt, path);
+                         if (this->FileIsExecutable(testPath)) {
+                           testPath =
+                             cmSystemTools::ToNormalizedPathOnDisk(testPath);
+                           if (this->FindBase->Validate(testPath)) {
+                             this->BestPath = testPath;
+                             this->DebugSearches.FoundAt(testPath);
+                             return true;
+                           }
                          }
+                         this->DebugSearches.FailedAt(testPath);
                          return false;
                        });
   }
-  bool FileIsValid(std::string const& file) const
+  bool FileIsExecutable(std::string const& file) const
   {
     if (!this->FileIsExecutableCMP0109(file)) {
       return false;
@@ -122,7 +117,7 @@ struct cmFindProgramHelper
       }
     }
 #endif
-    return this->FindBase->Validate(file);
+    return true;
   }
   bool FileIsExecutableCMP0109(std::string const& file) const
   {

+ 1 - 1
Source/cmLocalGenerator.cxx

@@ -2380,7 +2380,7 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
     dep = cmStrCat(this->GetCurrentBinaryDirectory(), '/', inName);
   }
 
-  dep = cmSystemTools::CollapseFullPath(dep, this->GetBinaryDirectory());
+  dep = cmSystemTools::CollapseFullPath(dep);
 
   return true;
 }

+ 1 - 1
Source/cmMakefile.cxx

@@ -2088,7 +2088,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, cmValue value,
       cmList files(value);
       for (auto& file : files) {
         if (!cmIsOff(file)) {
-          file = cmSystemTools::CollapseFullPath(file);
+          file = cmSystemTools::ToNormalizedPathOnDisk(file);
         }
       }
       nvalue = files.to_string();

+ 2 - 5
Source/cmMakefileTargetGenerator.cxx

@@ -683,9 +683,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
   // The object file should be checked for dependency integrity.
   std::string objFullPath =
     cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', obj);
-  objFullPath = cmSystemTools::CollapseFullPath(objFullPath);
-  std::string const srcFullPath =
-    cmSystemTools::CollapseFullPath(source.GetFullPath());
+  std::string const srcFullPath = source.GetFullPath();
   this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
                                            objFullPath, srcFullPath, scanner);
 
@@ -1560,8 +1558,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
               cmOutputConverter::SHELL)
          << " "
          << this->LocalGenerator->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(this->InfoFileNameFull),
-              cmOutputConverter::SHELL);
+              this->InfoFileNameFull, cmOutputConverter::SHELL);
   if (this->LocalGenerator->GetColorMakefile()) {
     depCmd << " \"--color=$(COLOR)\"";
   }

+ 0 - 1
Source/cmQtAutoGenerator.cxx

@@ -439,7 +439,6 @@ bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config,
 
   // Info file
   this->InfoFile_ = std::string(infoFile);
-  cmSystemTools::CollapseFullPath(this->InfoFile_);
   this->InfoDir_ = cmSystemTools::GetFilenamePath(this->InfoFile_);
 
   // Load info file time

+ 26 - 30
Source/cmSearchPath.cxx

@@ -62,7 +62,9 @@ void cmSearchPath::AddUserPath(const std::string& path)
   // Process them all from the current directory
   for (std::string const& p : outPaths) {
     this->AddPathInternal(
-      p, "", this->FC->Makefile->GetCurrentSourceDirectory().c_str());
+      cmSystemTools::CollapseFullPath(
+        p, this->FC->Makefile->GetCurrentSourceDirectory()),
+      "");
   }
 }
 
@@ -76,15 +78,17 @@ void cmSearchPath::AddCMakePath(const std::string& variable)
 
     for (std::string const& p : expanded) {
       this->AddPathInternal(
-        p, "", this->FC->Makefile->GetCurrentSourceDirectory().c_str());
+        cmSystemTools::CollapseFullPath(
+          p, this->FC->Makefile->GetCurrentSourceDirectory()),
+        "");
     }
   }
 }
 
 void cmSearchPath::AddEnvPath(const std::string& variable)
 {
-  std::vector<std::string> expanded;
-  cmSystemTools::GetPath(expanded, variable.c_str());
+  std::vector<std::string> expanded =
+    cmSystemTools::GetEnvPathNormalized(variable);
   for (std::string const& p : expanded) {
     this->AddPathInternal(p, "");
   }
@@ -97,9 +101,11 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
   // Get a path from a CMake variable.
   if (cmValue value = this->FC->Makefile->GetDefinition(variable)) {
     cmList expanded{ *value };
-
-    this->AddPrefixPaths(
-      expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str());
+    for (std::string& p : expanded) {
+      p = cmSystemTools::CollapseFullPath(
+        p, this->FC->Makefile->GetCurrentSourceDirectory());
+    }
+    this->AddPrefixPaths(expanded);
   }
 }
 
@@ -114,8 +120,8 @@ static std::string cmSearchPathStripBin(std::string const& s)
 
 void cmSearchPath::AddEnvPrefixPath(const std::string& variable, bool stripBin)
 {
-  std::vector<std::string> expanded;
-  cmSystemTools::GetPath(expanded, variable.c_str());
+  std::vector<std::string> expanded =
+    cmSystemTools::GetEnvPathNormalized(variable);
   if (stripBin) {
     std::transform(expanded.begin(), expanded.end(), expanded.begin(),
                    cmSearchPathStripBin);
@@ -151,8 +157,7 @@ void cmSearchPath::AddSuffixes(const std::vector<std::string>& suffixes)
   }
 }
 
-void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
-                                  const char* base)
+void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths)
 {
   assert(this->FC);
 
@@ -192,52 +197,43 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
               "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
           if (foundUnknown) {
             this->AddPathInternal(cmStrCat('/', archNoUnknown, dir, subdir),
-                                  cmStrCat('/', archNoUnknown, prefix), base);
+                                  cmStrCat('/', archNoUnknown, prefix));
           }
           this->AddPathInternal(cmStrCat('/', *arch, dir, subdir),
-                                cmStrCat('/', *arch, prefix), base);
+                                cmStrCat('/', *arch, prefix));
         } else {
           if (foundUnknown) {
             this->AddPathInternal(cmStrCat(dir, subdir, '/', archNoUnknown),
-                                  prefix, base);
+                                  prefix);
           }
-          this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix,
-                                base);
+          this->AddPathInternal(cmStrCat(dir, subdir, '/', *arch), prefix);
         }
       }
     }
     std::string add = dir + subdir;
     if (add != "/") {
-      this->AddPathInternal(add, prefix, base);
+      this->AddPathInternal(add, prefix);
     }
     if (subdir == "bin") {
-      this->AddPathInternal(dir + "sbin", prefix, base);
+      this->AddPathInternal(dir + "sbin", prefix);
     }
     if (!subdir.empty() && path != "/") {
-      this->AddPathInternal(path, prefix, base);
+      this->AddPathInternal(path, prefix);
     }
   }
 }
 
 void cmSearchPath::AddPathInternal(const std::string& path,
-                                   const std::string& prefix, const char* base)
+                                   const std::string& prefix)
 {
   assert(this->FC);
 
-  std::string collapsedPath = cmSystemTools::CollapseFullPath(path, base);
-
-  if (collapsedPath.empty()) {
+  if (path.empty()) {
     return;
   }
 
-  std::string collapsedPrefix;
-  if (!prefix.empty()) {
-    collapsedPrefix = cmSystemTools::CollapseFullPath(prefix, base);
-  }
-
   // Insert the path if has not already been emitted.
-  PathWithPrefix pathWithPrefix{ std::move(collapsedPath),
-                                 std::move(collapsedPrefix) };
+  PathWithPrefix pathWithPrefix{ path, prefix };
   if (this->FC->SearchPathsEmitted.insert(pathWithPrefix).second) {
     this->Paths.emplace_back(std::move(pathWithPrefix));
   }

+ 2 - 4
Source/cmSearchPath.h

@@ -55,12 +55,10 @@ public:
   void AddCMakePrefixPath(const std::string& variable);
   void AddEnvPrefixPath(const std::string& variable, bool stripBin = false);
   void AddSuffixes(const std::vector<std::string>& suffixes);
-  void AddPrefixPaths(const std::vector<std::string>& paths,
-                      const char* base = nullptr);
+  void AddPrefixPaths(const std::vector<std::string>& paths);
 
 protected:
-  void AddPathInternal(const std::string& path, const std::string& prefix,
-                       const char* base = nullptr);
+  void AddPathInternal(const std::string& path, const std::string& prefix);
 
   cmFindCommon* FC;
   std::vector<PathWithPrefix> Paths;

+ 6 - 11
Source/cmStateDirectory.cxx

@@ -21,7 +21,6 @@
 #include "cmState.h"
 #include "cmStatePrivate.h"
 #include "cmStateTypes.h"
-#include "cmSystemTools.h"
 #include "cmValue.h"
 
 static std::string const kBINARY_DIR = "BINARY_DIR";
@@ -36,11 +35,9 @@ std::string const& cmStateDirectory::GetCurrentSource() const
 
 void cmStateDirectory::SetCurrentSource(std::string const& dir)
 {
-  std::string& loc = this->DirectoryState->Location;
-  loc = dir;
-  cmSystemTools::ConvertToUnixSlashes(loc);
-  loc = cmSystemTools::CollapseFullPath(loc);
-  this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
+  this->DirectoryState->Location = dir;
+  this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR",
+                                this->DirectoryState->Location);
 }
 
 std::string const& cmStateDirectory::GetCurrentBinary() const
@@ -50,11 +47,9 @@ std::string const& cmStateDirectory::GetCurrentBinary() const
 
 void cmStateDirectory::SetCurrentBinary(std::string const& dir)
 {
-  std::string& loc = this->DirectoryState->OutputLocation;
-  loc = dir;
-  cmSystemTools::ConvertToUnixSlashes(loc);
-  loc = cmSystemTools::CollapseFullPath(loc);
-  this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
+  this->DirectoryState->OutputLocation = dir;
+  this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR",
+                                this->DirectoryState->OutputLocation);
 }
 
 cmStateDirectory::cmStateDirectory(

+ 44 - 5
Source/cmSystemTools.cxx

@@ -20,6 +20,8 @@
 
 #include "cmSystemTools.h"
 
+#include <iterator>
+
 #include <cm/optional>
 #include <cmext/algorithm>
 #include <cmext/string_view>
@@ -1614,20 +1616,57 @@ cm::optional<std::string> cmSystemTools::GetEnvVar(std::string const& var)
   return result;
 }
 
-std::vector<std::string> cmSystemTools::SplitEnvPath(std::string const& value)
+std::vector<std::string> cmSystemTools::GetEnvPathNormalized(
+  std::string const& var)
+{
+  std::vector<std::string> result;
+  if (cm::optional<std::string> env = cmSystemTools::GetEnvVar(var)) {
+    std::vector<std::string> p = cmSystemTools::SplitEnvPathNormalized(*env);
+    std::move(p.begin(), p.end(), std::back_inserter(result));
+  }
+  return result;
+}
+
+std::vector<std::string> cmSystemTools::SplitEnvPath(cm::string_view in)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   static cm::string_view sep = ";"_s;
 #else
   static cm::string_view sep = ":"_s;
 #endif
-  std::vector<std::string> paths = cmTokenize(value, sep);
-  for (std::string& p : paths) {
-    SystemTools::ConvertToUnixSlashes(p);
+  std::vector<std::string> paths;
+  cm::string_view::size_type e = 0;
+  for (;;) {
+    cm::string_view::size_type b = in.find_first_not_of(sep, e);
+    if (b == cm::string_view::npos) {
+      break;
+    }
+    e = in.find_first_of(sep, b);
+    if (e == cm::string_view::npos) {
+      paths.emplace_back(in.substr(b));
+      break;
+    }
+    paths.emplace_back(in.substr(b, e - b));
   }
   return paths;
 }
 
+std::vector<std::string> cmSystemTools::SplitEnvPathNormalized(
+  cm::string_view in)
+{
+  std::vector<std::string> paths = cmSystemTools::SplitEnvPath(in);
+  std::transform(paths.begin(), paths.end(), paths.begin(),
+                 cmSystemTools::ToNormalizedPathOnDisk);
+  return paths;
+}
+
+std::string cmSystemTools::ToNormalizedPathOnDisk(std::string p)
+{
+  p = cmSystemTools::CollapseFullPath(p);
+  cmSystemTools::ConvertToUnixSlashes(p);
+  return p;
+}
+
 #ifndef CMAKE_BOOTSTRAP
 bool cmSystemTools::UnsetEnv(const char* value)
 {
@@ -2739,7 +2778,7 @@ cm::optional<std::string> cmSystemTools::GetCMakeConfigDirectory()
 
 std::string cmSystemTools::GetCurrentWorkingDirectory()
 {
-  return cmSystemTools::CollapseFullPath(
+  return cmSystemTools::ToNormalizedPathOnDisk(
     cmsys::SystemTools::GetCurrentWorkingDirectory());
 }
 

+ 6 - 1
Source/cmSystemTools.h

@@ -399,7 +399,12 @@ public:
                                      std::string const& in);
 
   static cm::optional<std::string> GetEnvVar(std::string const& var);
-  static std::vector<std::string> SplitEnvPath(std::string const& value);
+  static std::vector<std::string> GetEnvPathNormalized(std::string const& var);
+
+  static std::vector<std::string> SplitEnvPath(cm::string_view in);
+  static std::vector<std::string> SplitEnvPathNormalized(cm::string_view in);
+
+  static std::string ToNormalizedPathOnDisk(std::string p);
 
 #ifndef CMAKE_BOOTSTRAP
   /** Remove an environment variable */

+ 35 - 45
Source/cmake.cxx

@@ -689,7 +689,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         cmSystemTools::Stdout("loading initial cache file " + value + "\n");
         // Resolve script path specified on command line
         // relative to $PWD.
-        auto path = cmSystemTools::CollapseFullPath(value);
+        auto path = cmSystemTools::ToNormalizedPathOnDisk(value);
         state->ReadListFile(args, path);
         return true;
       } },
@@ -778,10 +778,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
     snapshot.SetDefaultDefinitions();
     cmMakefile mf(gg, snapshot);
     if (this->GetWorkingMode() != NORMAL_MODE) {
-      std::string file(cmSystemTools::CollapseFullPath(path));
-      cmSystemTools::ConvertToUnixSlashes(file);
-      mf.SetScriptModeFile(file);
-
+      mf.SetScriptModeFile(cmSystemTools::ToNormalizedPathOnDisk(path));
       mf.SetArgcArgv(args);
     }
     if (!cmSystemTools::FileExists(path, true)) {
@@ -955,10 +952,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
       cmSystemTools::Error("No source directory specified for -S");
       return false;
     }
-    std::string path = cmSystemTools::CollapseFullPath(value);
-    cmSystemTools::ConvertToUnixSlashes(path);
-
-    state->SetHomeDirectoryViaCommandLine(path);
+    state->SetHomeDirectoryViaCommandLine(
+      cmSystemTools::ToNormalizedPathOnDisk(value));
     return true;
   };
 
@@ -967,9 +962,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
       cmSystemTools::Error("No build directory specified for -B");
       return false;
     }
-    std::string path = cmSystemTools::CollapseFullPath(value);
-    cmSystemTools::ConvertToUnixSlashes(path);
-    state->SetHomeOutputDirectory(path);
+    state->SetHomeOutputDirectory(
+      cmSystemTools::ToNormalizedPathOnDisk(value));
     haveBArg = true;
     return true;
   };
@@ -1073,7 +1067,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
     CommandArgument{ "--graphviz", "No file specified for --graphviz",
                      CommandArgument::Values::One,
                      [](std::string const& value, cmake* state) -> bool {
-                       state->SetGraphVizFile(value);
+                       state->SetGraphVizFile(
+                         cmSystemTools::ToNormalizedPathOnDisk(value));
                        return true;
                      } },
 
@@ -1277,23 +1272,22 @@ void cmake::SetArgs(const std::vector<std::string>& args)
                        return false;
 #endif
                      } },
-    CommandArgument{
-      "--debugger-dap-log", "No file specified for --debugger-dap-log",
-      CommandArgument::Values::One,
-      [](std::string const& value, cmake* state) -> bool {
+    CommandArgument{ "--debugger-dap-log",
+                     "No file specified for --debugger-dap-log",
+                     CommandArgument::Values::One,
+                     [](std::string const& value, cmake* state) -> bool {
 #ifdef CMake_ENABLE_DEBUGGER
-        std::string path = cmSystemTools::CollapseFullPath(value);
-        cmSystemTools::ConvertToUnixSlashes(path);
-        state->DebuggerDapLogFile = path;
-        return true;
+                       state->DebuggerDapLogFile =
+                         cmSystemTools::ToNormalizedPathOnDisk(value);
+                       return true;
 #else
-        static_cast<void>(value);
-        static_cast<void>(state);
-        cmSystemTools::Error(
-          "CMake was not built with support for --debugger-dap-log");
-        return false;
+                       static_cast<void>(value);
+                       static_cast<void>(state);
+                       cmSystemTools::Error("CMake was not built with support "
+                                            "for --debugger-dap-log");
+                       return false;
 #endif
-      } },
+                     } },
   };
 
 #if defined(CMAKE_HAVE_VS_GENERATORS)
@@ -1315,9 +1309,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
   arguments.emplace_back(
     "--profiling-output", "No path specified for --profiling-output",
     CommandArgument::Values::One,
-    [&](std::string const& value, cmake*) -> bool {
-      profilingOutput = cmSystemTools::CollapseFullPath(value);
-      cmSystemTools::ConvertToUnixSlashes(profilingOutput);
+    [&profilingOutput](std::string const& value, cmake*) -> bool {
+      profilingOutput = cmSystemTools::ToNormalizedPathOnDisk(value);
       return true;
     });
   arguments.emplace_back("--preset", "No preset specified for --preset",
@@ -1587,7 +1580,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
 
     if (!expandedPreset->GraphVizFile.empty()) {
       if (this->GraphVizFile.empty()) {
-        this->SetGraphVizFile(expandedPreset->GraphVizFile);
+        this->SetGraphVizFile(
+          cmSystemTools::CollapseFullPath(expandedPreset->GraphVizFile));
       }
     }
 
@@ -1778,8 +1772,7 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
   bool is_source_dir = false;
   bool is_empty_directory = false;
   if (cmSystemTools::FileIsDirectory(arg)) {
-    std::string path = cmSystemTools::CollapseFullPath(arg);
-    cmSystemTools::ConvertToUnixSlashes(path);
+    std::string path = cmSystemTools::ToNormalizedPathOnDisk(arg);
     std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
     std::string listFile = cmStrCat(path, "/CMakeLists.txt");
 
@@ -1794,7 +1787,7 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
       is_source_dir = true;
     }
   } else if (cmSystemTools::FileExists(arg)) {
-    std::string fullPath = cmSystemTools::CollapseFullPath(arg);
+    std::string fullPath = cmSystemTools::ToNormalizedPathOnDisk(arg);
     std::string name = cmSystemTools::GetFilenameName(fullPath);
     name = cmSystemTools::LowerCase(name);
     if (name == "cmakecache.txt"_s) {
@@ -1845,14 +1838,13 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
     if (is_source_dir) {
       this->SetHomeDirectoryViaCommandLine(listPath);
       if (no_build_tree) {
-        std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-        this->SetHomeOutputDirectory(cwd);
+        this->SetHomeOutputDirectory(
+          cmSystemTools::GetCurrentWorkingDirectory());
       }
     } else if (no_source_tree && no_build_tree) {
       this->SetHomeDirectory(listPath);
-
-      std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-      this->SetHomeOutputDirectory(cwd);
+      this->SetHomeOutputDirectory(
+        cmSystemTools::GetCurrentWorkingDirectory());
     } else if (no_build_tree) {
       this->SetHomeOutputDirectory(listPath);
     }
@@ -1860,18 +1852,16 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
     if (no_source_tree) {
       // We didn't find a CMakeLists.txt and it wasn't specified
       // with -S. Assume it is the path to the source tree
-      std::string full = cmSystemTools::CollapseFullPath(arg);
-      this->SetHomeDirectory(full);
+      this->SetHomeDirectory(cmSystemTools::ToNormalizedPathOnDisk(arg));
     }
     if (no_build_tree && !no_source_tree && is_empty_directory) {
       // passed `-S <path> <build_dir> when build_dir is an empty directory
-      std::string full = cmSystemTools::CollapseFullPath(arg);
-      this->SetHomeOutputDirectory(full);
+      this->SetHomeOutputDirectory(cmSystemTools::ToNormalizedPathOnDisk(arg));
     } else if (no_build_tree) {
       // We didn't find a CMakeCache.txt and it wasn't specified
       // with -B. Assume the current working directory as the build tree.
-      std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-      this->SetHomeOutputDirectory(cwd);
+      this->SetHomeOutputDirectory(
+        cmSystemTools::GetCurrentWorkingDirectory());
       used_provided_path = false;
     }
   }

+ 1 - 7
Source/cmake.h

@@ -26,7 +26,6 @@
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
-#include "cmSystemTools.h"
 #include "cmValue.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -300,12 +299,7 @@ public:
   }
 
   //! Set the name of the graphviz file.
-  void SetGraphVizFile(std::string const& ts)
-  {
-    std::string path = cmSystemTools::CollapseFullPath(ts);
-    cmSystemTools::ConvertToUnixSlashes(path);
-    this->GraphVizFile = path;
-  }
+  void SetGraphVizFile(std::string const& ts) { this->GraphVizFile = ts; }
 
   bool IsAKnownSourceExtension(cm::string_view ext) const
   {

+ 3 - 3
Source/cmakemain.cxx

@@ -601,7 +601,7 @@ int do_build(int ac, char const* const* av)
         }
       }
       if (!matched && i == 0) {
-        dir = cmSystemTools::CollapseFullPath(arg);
+        dir = cmSystemTools::ToNormalizedPathOnDisk(arg);
         matched = true;
         parsed = true;
       }
@@ -873,7 +873,7 @@ int do_install(int ac, char const* const* av)
   };
 
   if (ac >= 3) {
-    dir = cmSystemTools::CollapseFullPath(av[2]);
+    dir = cmSystemTools::ToNormalizedPathOnDisk(av[2]);
 
     std::vector<std::string> inputArgs;
     inputArgs.reserve(ac - 3);
@@ -1098,7 +1098,7 @@ int do_open(int ac, char const* const* av)
   for (int i = 2; i < ac; ++i) {
     switch (doing) {
       case DoingDir:
-        dir = cmSystemTools::CollapseFullPath(av[i]);
+        dir = cmSystemTools::ToNormalizedPathOnDisk(av[i]);
         doing = DoingNone;
         break;
       default:

+ 9 - 9
Source/cmcmd.cxx

@@ -1347,10 +1347,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
 
       // Create a local generator configured for the directory in
       // which dependencies will be scanned.
-      homeDir = cmSystemTools::CollapseFullPath(homeDir);
-      startDir = cmSystemTools::CollapseFullPath(startDir);
-      homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir);
-      startOutDir = cmSystemTools::CollapseFullPath(startOutDir);
+      homeDir = cmSystemTools::ToNormalizedPathOnDisk(homeDir);
+      startDir = cmSystemTools::ToNormalizedPathOnDisk(startDir);
+      homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(homeOutDir);
+      startOutDir = cmSystemTools::ToNormalizedPathOnDisk(startOutDir);
       cm.SetHomeDirectory(homeDir);
       cm.SetHomeOutputDirectory(homeOutDir);
       cm.GetCurrentSnapshot().SetDefaultDefinitions();
@@ -1643,10 +1643,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
       std::string startDir;
       std::string homeOutDir;
       std::string startOutDir;
-      homeDir = cmSystemTools::CollapseFullPath(args[4]);
-      startDir = cmSystemTools::CollapseFullPath(args[5]);
-      homeOutDir = cmSystemTools::CollapseFullPath(args[6]);
-      startOutDir = cmSystemTools::CollapseFullPath(args[7]);
+      homeDir = cmSystemTools::ToNormalizedPathOnDisk(args[4]);
+      startDir = cmSystemTools::ToNormalizedPathOnDisk(args[5]);
+      homeOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[6]);
+      startOutDir = cmSystemTools::ToNormalizedPathOnDisk(args[7]);
       cm.SetHomeDirectory(homeDir);
       cm.SetHomeOutputDirectory(homeOutDir);
       cm.GetCurrentSnapshot().SetDefaultDefinitions();
@@ -2413,7 +2413,7 @@ int cmVSLink::LinkIncremental()
 
   // Create a resource file referencing the manifest.
   std::string absManifestFile =
-    cmSystemTools::CollapseFullPath(this->ManifestFile);
+    cmSystemTools::ToNormalizedPathOnDisk(this->ManifestFile);
   if (this->Verbose) {
     std::cout << "Create " << this->ManifestFileRC << '\n';
   }

+ 8 - 8
Tests/FindPackageTest/CMakeLists.txt

@@ -204,7 +204,7 @@ if(UNIX
   # The result must preserve the /symlink/ path.
   set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/symlink/cmake")
   if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}")
-    message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")")
+    message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to\n  \"${SetFoundResolved_DIR}\"\nnot the expected\n  \"${SetFoundResolved_EXPECTED}\"")
   endif()
 
   # This part of the test only works if there are no symlinks in our path.
@@ -217,7 +217,7 @@ if(UNIX
     # ./symlink points back here so it should be gone when resolved.
     set(SetFoundResolved_EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
     if(NOT "${SetFoundResolved_DIR}" STREQUAL "${SetFoundResolved_EXPECTED}")
-      message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to \"${SetFoundResolved_DIR}\" (expected \"${SetFoundResolved_EXPECTED}\")")
+      message(SEND_ERROR "SetFoundResolved_DIR set by find_package() is set to\n  \"${SetFoundResolved_DIR}\"\nnot the expected\n  \"${SetFoundResolved_EXPECTED}\"")
     endif()
   endif()
 
@@ -492,15 +492,15 @@ set(Relocatable_FIND_REQUIRED_BComp 1)
 include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
 
 if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
-  message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")")
+  message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to\n  \"${RELOC_INCLUDE_DIR}\"\nnot the expected\n  \"${CMAKE_CURRENT_BINARY_DIR}/include\"")
 endif()
 
 if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/")
-  message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")")
+  message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to\n  \"${RELOC_SHARE_DIR}\"\nnot the expected\n  \"${CMAKE_CURRENT_BINARY_DIR}/share/\"")
 endif()
 
 if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
-  message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
+  message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to\n  \"${RELOC_BUILD_DIR}\"\nnot the expected\n  \"${CMAKE_CURRENT_BINARY_DIR}\"")
 endif()
 
 if(NOT DEFINED Relocatable_FOUND)
@@ -527,15 +527,15 @@ set(Relocatable_FIND_REQUIRED_BComp 1)
 include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
 
 if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
-  message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")")
+  message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to\n  \"${RELOC_INCLUDE_DIR}\"\nnot the expected\n  \"${CMAKE_CURRENT_BINARY_DIR}/include\"")
 endif()
 
 if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/")
-  message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")")
+  message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to\n  \"${RELOC_SHARE_DIR}\"\nnot the expected\n  \"${CMAKE_CURRENT_BINARY_DIR}/share/\"")
 endif()
 
 if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
-  message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
+  message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to\n  \"${RELOC_BUILD_DIR}\"\nnot the expected\n  \"${CMAKE_CURRENT_BINARY_DIR}\"")
 endif()
 
 if(NOT DEFINED Relocatable_FOUND)

+ 22 - 22
Tests/RunCMake/CXXModules/check-json.cmake

@@ -50,8 +50,8 @@ endfunction ()
 
 function (check_json_value path actual_type expect_type actual_value expect_value)
   if (NOT actual_type STREQUAL expect_type)
-    list(APPEND RunCMake_TEST_FAILED
-      "Type mismatch at ${path}: ${actual_type} vs. ${expect_type}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Type mismatch at:\n ${path}\nexpected:\n ${expect_type}\nactual:\n ${actual_type}\n")
     set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
     return ()
   endif ()
@@ -60,13 +60,13 @@ function (check_json_value path actual_type expect_type actual_value expect_valu
     # Nothing to check
   elseif (actual_type STREQUAL BOOLEAN)
     if (NOT actual_value STREQUAL expect_value)
-      list(APPEND RunCMake_TEST_FAILED
-        "Boolean mismatch at ${path}: ${actual_value} vs. ${expect_value}")
+      string(APPEND RunCMake_TEST_FAILED
+        "Boolean mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n")
     endif ()
   elseif (actual_type STREQUAL NUMBER)
     if (NOT actual_value EQUAL expect_value)
-      list(APPEND RunCMake_TEST_FAILED
-        "Number mismatch at ${path}: ${actual_value} vs. ${expect_value}")
+      string(APPEND RunCMake_TEST_FAILED
+        "Number mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n")
     endif ()
   elseif (actual_type STREQUAL STRING)
     # Allow some values to be ignored.
@@ -79,24 +79,24 @@ function (check_json_value path actual_type expect_type actual_value expect_valu
       string(REPLACE "\\" "/" actual_value_check "${actual_value}")
       string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}")
       if (NOT actual_value_check MATCHES "^${expect_value_expanded}$")
-        list(APPEND RunCMake_TEST_FAILED
-          "String mismatch (path regex) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$")
+        string(APPEND RunCMake_TEST_FAILED
+          "String mismatch (path regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n")
       endif ()
     elseif (expect_value MATCHES "^REGEX:")
       if (NOT actual_value MATCHES "^${expect_value_expanded}$")
-        list(APPEND RunCMake_TEST_FAILED
-          "String mismatch (regex) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$")
+        string(APPEND RunCMake_TEST_FAILED
+          "String mismatch (regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n")
       endif ()
     elseif (expect_value MATCHES "^PATH:")
       string(REPLACE "\\" "/" actual_value_check "${actual_value}")
       string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}")
       if (NOT actual_value_check STREQUAL "${expect_value_expanded}")
-        list(APPEND RunCMake_TEST_FAILED
-          "String mismatch (path) at ${path}: ${actual_value} vs. ^${expect_value_expanded}$")
+        string(APPEND RunCMake_TEST_FAILED
+          "String mismatch (path) at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n")
       endif ()
     elseif (NOT actual_value STREQUAL expect_value_expanded)
-      list(APPEND RunCMake_TEST_FAILED
-        "String mismatch at ${path}: ${actual_value} vs. ${expect_value_expanded}")
+      string(APPEND RunCMake_TEST_FAILED
+        "String mismatch at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n")
     endif ()
   elseif (actual_type STREQUAL ARRAY)
     check_json_array("${path}" "${actual_value}" "${expect_value}")
@@ -130,11 +130,11 @@ function (check_json_array path actual expect)
 
   set(iter_len "${actual_len}")
   if (actual_len LESS expect_len)
-    list(APPEND RunCMake_TEST_FAILED
-      "Missing array items at ${path}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Missing array items at:\n ${path}\n")
   elseif (expect_len LESS actual_len)
-    list(APPEND RunCMake_TEST_FAILED
-      "Extra array items at ${path}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Extra array items at:\n ${path}\n")
     set(iter_len "${expect_len}")
   endif ()
 
@@ -200,13 +200,13 @@ function (check_json_object path actual expect)
 
   if (actual_keys_missed)
     string(REPLACE ";" ", " actual_keys_missed_text "${actual_keys_missed}")
-    list(APPEND RunCMake_TEST_FAILED
-      "Extra unexpected members at ${path}: ${actual_keys_missed_text}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Extra unexpected members at:\n ${path}\nactual:\n ${actual_keys_missed_text}\n")
   endif ()
   if (expect_keys_missed)
     string(REPLACE ";" ", " expect_keys_missed_text "${expect_keys_missed}")
-    list(APPEND RunCMake_TEST_FAILED
-      "Missing expected members at ${path}: ${expect_keys_missed_text}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Missing expected members at\n ${path}\nactual:\n ${expect_keys_missed_text}\n")
   endif ()
 
   foreach (key IN LISTS common_keys)

+ 1 - 1
Tests/RunCMake/CommandLine/C_basic-stdout.txt

@@ -1 +1 @@
-loading initial cache file ../C_basic_initial-cache.txt
+loading initial cache file \.\./C_basic_initial-cache.txt

+ 2 - 1
Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt

@@ -1 +1,2 @@
-loading initial cache file .*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt
+loading initial cache file [^
+]*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt

+ 2 - 2
Tests/RunCMake/CommandLine/ExplicitDirs-C_buildsrcdir-stdout.txt

@@ -1,2 +1,2 @@
-loading initial cache file .*initial-cache.txt
-.*
+loading initial cache file [^
+]*initial-cache.txt

+ 0 - 0
Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp → Tests/RunCMake/VS10Project/CSharpSourceGroup/Images/empty.bmp


+ 1 - 1
Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake

@@ -11,7 +11,7 @@ include(${RunCMake_TEST_SOURCE_DIR}/VsCsharpSourceGroupHelpers.cmake)
 set(SOURCE_GROUPS_TO_FIND
   "CSharpSourceGroup\\\\foo\\.cs"
   "CSharpSourceGroup\\\\nested\\\\baz\\.cs"
-  "CSharpSourceGroup\\\\images\\\\empty\\.bmp"
+  "Images\\\\empty\\.bmp"
   "VsCsharpSourceGroup\\.png"
   "AssemblyInfo\\.cs"
 )

+ 1 - 1
Tests/RunCMake/get_filename_component/KnownComponents.cmake

@@ -1,7 +1,7 @@
 # Assertion macro
 macro(check desc actual expect)
   if(NOT "x${actual}" STREQUAL "x${expect}")
-    message(SEND_ERROR "${desc}: got \"${actual}\", not \"${expect}\"")
+    message(SEND_ERROR "${desc}: got\n  \"${actual}\"\nnot\n  \"${expect}\"")
   endif()
 endmacro()