1
0
Эх сурвалжийг харах

cmSystemTools: Add GetLogicalWorkingDirectory

Track the current working directory with symbolic links preserved.
Brad King 1 жил өмнө
parent
commit
5aed3ee49d

+ 6 - 5
Source/CPack/cpack.cxx

@@ -113,7 +113,7 @@ int main(int argc, char const* const* argv)
   log.SetOutputPrefix("CPack: ");
   log.SetVerbosePrefix("CPack Verbose: ");
 
-  if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
+  if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
     cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
                 "Current working directory cannot be established.\n");
     return 1;
@@ -255,7 +255,7 @@ int main(int argc, char const* const* argv)
 
   // Set up presets
   if (!preset.empty() || listPresets) {
-    const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+    const auto workingDirectory = cmSystemTools::GetLogicalWorkingDirectory();
 
     auto const presetGeneratorsPresent =
       [&generators](const cmCMakePresetsGraph::PackagePreset& p) {
@@ -350,7 +350,8 @@ int main(int argc, char const* const* argv)
       return 1;
     }
 
-    cmSystemTools::ChangeDirectory(expandedConfigurePreset->BinaryDir);
+    cmSystemTools::SetLogicalWorkingDirectory(
+      expandedConfigurePreset->BinaryDir);
 
     auto presetEnvironment = expandedPreset->Environment;
     for (auto const& var : presetEnvironment) {
@@ -408,7 +409,7 @@ int main(int argc, char const* const* argv)
   if (!cpackConfigFile.empty()) {
     cpackConfigFile = cmSystemTools::ToNormalizedPathOnDisk(cpackConfigFile);
   } else {
-    cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(),
+    cpackConfigFile = cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(),
                                "/CPackConfig.cmake");
     cpackConfigFileSpecified = false;
   }
@@ -488,7 +489,7 @@ int main(int argc, char const* const* argv)
         cpackProjectDirectory = cmSystemTools::CollapseFullPath(*pd);
       } else {
         // Default to the current working directory.
-        cpackProjectDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+        cpackProjectDirectory = cmSystemTools::GetLogicalWorkingDirectory();
       }
     }
     globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);

+ 1 - 1
Source/CTest/cmCTestLaunchReporter.cxx

@@ -25,7 +25,7 @@ cmCTestLaunchReporter::cmCTestLaunchReporter()
   this->Passthru = true;
   this->Status.Finished = true;
   this->ExitCode = 1;
-  this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
+  this->CWD = cmSystemTools::GetLogicalWorkingDirectory();
 
   this->ComputeFileNames();
 

+ 1 - 1
Source/CTest/cmCTestScriptHandler.cxx

@@ -188,7 +188,7 @@ void cmCTestScriptHandler::CreateCMake()
     cm::make_unique<cmGlobalGenerator>(this->CMake.get());
 
   cmStateSnapshot snapshot = this->CMake->GetCurrentSnapshot();
-  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+  std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
   snapshot.GetDirectory().SetCurrentSource(cwd);
   snapshot.GetDirectory().SetCurrentBinary(cwd);
   this->Makefile =

+ 5 - 5
Source/CTest/cmCTestTestHandler.cxx

@@ -128,7 +128,7 @@ bool cmCTestSubdirCommand(std::vector<std::string> const& args,
     status.SetError("called with incorrect number of arguments");
     return false;
   }
-  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+  std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
   for (std::string const& arg : args) {
     std::string fname;
 
@@ -154,7 +154,7 @@ bool cmCTestAddSubdirectoryCommand(std::vector<std::string> const& args,
   }
 
   std::string fname =
-    cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), '/', args[0]);
+    cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), '/', args[0]);
 
   return ReadSubdirectory(std::move(fname), status);
 }
@@ -354,7 +354,7 @@ int cmCTestTestHandler::ProcessHandler()
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                      (this->MemCheck ? "Memory check" : "Test")
                        << " project "
-                       << cmSystemTools::GetCurrentWorkingDirectory()
+                       << cmSystemTools::GetLogicalWorkingDirectory()
                        << std::endl,
                      this->Quiet);
   if (!this->PreProcessHandler()) {
@@ -2385,7 +2385,7 @@ bool cmCTestTestHandler::SetDirectoryProperties(
     }
     std::string const& val = *it;
     for (cmCTestTestProperties& rt : this->TestList) {
-      std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+      std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
       if (cwd == rt.Directory) {
         if (key == "LABELS"_s) {
           cmList DirectoryLabels{ val };
@@ -2449,7 +2449,7 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
   cmCTestTestProperties test;
   test.Name = testname;
   test.Args = args;
-  test.Directory = cmSystemTools::GetCurrentWorkingDirectory();
+  test.Directory = cmSystemTools::GetLogicalWorkingDirectory();
   cmCTestOptionalLog(this->CTest, DEBUG,
                      "Set test directory: " << test.Directory << std::endl,
                      this->Quiet);

+ 1 - 1
Source/CursesDialog/ccmake.cxx

@@ -101,7 +101,7 @@ int main(int argc, char const* const* argv)
     }
   }
 
-  std::string cacheDir = cmSystemTools::GetCurrentWorkingDirectory();
+  std::string cacheDir = cmSystemTools::GetLogicalWorkingDirectory();
   for (i = 1; i < args.size(); ++i) {
     std::string const& arg = args[i];
     if (cmHasPrefix(arg, "-B")) {

+ 1 - 1
Source/QtDialog/CMakeSetup.cxx

@@ -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::GetCurrentWorkingDirectory()));
+          QString::fromStdString(cmSystemTools::GetLogicalWorkingDirectory()));
       }
     }
   }

+ 4 - 4
Source/cmCTest.cxx

@@ -574,7 +574,7 @@ bool cmCTest::UpdateCTestConfiguration()
   if (!this->GetCTestConfiguration("BuildDirectory").empty()) {
     this->Impl->BinaryDir = this->GetCTestConfiguration("BuildDirectory");
     if (this->Impl->TestDir.empty()) {
-      cmSystemTools::ChangeDirectory(this->Impl->BinaryDir);
+      cmSystemTools::SetLogicalWorkingDirectory(this->Impl->BinaryDir);
     }
   }
   this->Impl->TimeOut =
@@ -705,7 +705,7 @@ int cmCTest::ProcessSteps()
   this->Impl->Verbose = true;
   this->Impl->ProduceXML = true;
 
-  const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
+  const std::string currDir = cmSystemTools::GetLogicalWorkingDirectory();
   std::string workDir = currDir;
   if (!this->Impl->TestDir.empty()) {
     workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir);
@@ -1555,7 +1555,7 @@ bool cmCTest::AddVariableDefinition(const std::string& arg)
 bool cmCTest::SetArgsFromPreset(const std::string& presetName,
                                 bool listPresets)
 {
-  const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+  const auto workingDirectory = cmSystemTools::GetLogicalWorkingDirectory();
 
   cmCMakePresetsGraph settingsFile;
   auto result = settingsFile.ReadProjectPresets(workingDirectory);
@@ -2668,7 +2668,7 @@ int cmCTest::ExecuteTests()
   this->Impl->ExtraVerbose = this->Impl->Verbose;
   this->Impl->Verbose = true;
 
-  const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
+  const std::string currDir = cmSystemTools::GetLogicalWorkingDirectory();
   std::string workDir = currDir;
   if (!this->Impl->TestDir.empty()) {
     workDir = cmSystemTools::ToNormalizedPathOnDisk(this->Impl->TestDir);

+ 1 - 1
Source/cmFileCommand.cxx

@@ -3847,7 +3847,7 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
 
       if (!cmSystemTools::FileIsFullPath(inFile)) {
         inFile =
-          cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/", inFile);
+          cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), "/", inFile);
       }
     }
 

+ 1 - 1
Source/cmInstallScriptHandler.cxx

@@ -133,7 +133,7 @@ int cmInstallScriptHandler::install(unsigned int j)
 InstallScript::InstallScript(const std::vector<std::string>& cmd)
 {
   this->name = cmSystemTools::RelativePath(
-    cmSystemTools::GetCurrentWorkingDirectory(), cmd.back());
+    cmSystemTools::GetLogicalWorkingDirectory(), cmd.back());
   this->command = cmd;
 }
 

+ 31 - 5
Source/cmSystemTools.cxx

@@ -1916,12 +1916,12 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
                               std::string const& format, int compressionLevel)
 {
 #if !defined(CMAKE_BOOTSTRAP)
-  cmWorkingDirectory workdir(cmSystemTools::GetCurrentWorkingDirectory());
+  cmWorkingDirectory workdir(cmSystemTools::GetLogicalWorkingDirectory());
   if (!workingDirectory.empty()) {
     workdir.SetDirectory(workingDirectory);
   }
 
-  const std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+  const std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
   cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary);
   if (!fout) {
     std::string e = cmStrCat("Cannot open output file \"", outFileName,
@@ -2555,6 +2555,24 @@ unsigned int cmSystemTools::RandomSeed()
 #endif
 }
 
+namespace {
+std::string InitLogicalWorkingDirectory()
+{
+  std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
+  std::string pwd;
+  if (cmSystemTools::GetEnv("PWD", pwd)) {
+    std::string const pwd_real = cmSystemTools::GetRealPath(pwd);
+    if (pwd_real == cwd) {
+      cwd = std::move(pwd);
+    }
+  }
+  return cwd;
+}
+
+std::string cmSystemToolsLogicalWorkingDirectory =
+  InitLogicalWorkingDirectory();
+}
+
 static std::string cmSystemToolsCMakeCommand;
 static std::string cmSystemToolsCTestCommand;
 static std::string cmSystemToolsCPackCommand;
@@ -2779,10 +2797,18 @@ cm::optional<std::string> cmSystemTools::GetCMakeConfigDirectory()
   return config;
 }
 
-std::string cmSystemTools::GetCurrentWorkingDirectory()
+std::string const& cmSystemTools::GetLogicalWorkingDirectory()
+{
+  return cmSystemToolsLogicalWorkingDirectory;
+}
+
+cmsys::Status cmSystemTools::SetLogicalWorkingDirectory(std::string const& lwd)
 {
-  return cmSystemTools::ToNormalizedPathOnDisk(
-    cmsys::SystemTools::GetCurrentWorkingDirectory());
+  cmsys::Status status = cmSystemTools::ChangeDirectory(lwd);
+  if (status) {
+    cmSystemToolsLogicalWorkingDirectory = lwd;
+  }
+  return status;
 }
 
 void cmSystemTools::MakefileColorEcho(int color, const char* message,

+ 5 - 2
Source/cmSystemTools.h

@@ -534,8 +534,11 @@ public:
   static cm::optional<std::string> GetSystemConfigDirectory();
   static cm::optional<std::string> GetCMakeConfigDirectory();
 
-  /** Get the CWD mapped through the KWSys translation map.  */
-  static std::string GetCurrentWorkingDirectory();
+  static std::string const& GetLogicalWorkingDirectory();
+
+  /** The logical working directory may contain symlinks but must not
+      contain any '../' path components.  */
+  static cmsys::Status SetLogicalWorkingDirectory(std::string const& lwd);
 
   /** Echo a message in color using KWSys's Terminal cprintf.  */
   static void MakefileColorEcho(int color, const char* message, bool newLine,

+ 2 - 2
Source/cmWorkingDirectory.cxx

@@ -7,7 +7,7 @@
 
 cmWorkingDirectory::cmWorkingDirectory(std::string const& newdir)
 {
-  this->OldDir = cmSystemTools::GetCurrentWorkingDirectory();
+  this->OldDir = cmSystemTools::GetLogicalWorkingDirectory();
   this->SetDirectory(newdir);
 }
 
@@ -18,7 +18,7 @@ cmWorkingDirectory::~cmWorkingDirectory()
 
 bool cmWorkingDirectory::SetDirectory(std::string const& newdir)
 {
-  cmsys::Status status = cmSystemTools::ChangeDirectory(newdir);
+  cmsys::Status status = cmSystemTools::SetLogicalWorkingDirectory(newdir);
   if (status) {
     this->Error.clear();
     return true;

+ 17 - 17
Source/cmake.cxx

@@ -286,7 +286,7 @@ cmDocumentationEntry cmake::CMAKE_STANDARD_OPTIONS_TABLE[18] = {
 };
 
 cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
-  : CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory())
+  : CMakeWorkingDirectory(cmSystemTools::GetLogicalWorkingDirectory())
   , FileTimeCache(cm::make_unique<cmFileTimeCache>())
 #ifndef CMAKE_BOOTSTRAP
   , VariableWatch(cm::make_unique<cmVariableWatch>())
@@ -637,8 +637,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
     // Documented behavior of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
     // set to $PWD for -P mode.
     state->SetWorkingMode(SCRIPT_MODE);
-    state->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
-    state->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+    state->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+    state->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
     state->ReadListFile(args, path);
     return true;
   };
@@ -792,16 +792,16 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
 
 bool cmake::FindPackage(const std::vector<std::string>& args)
 {
-  this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
-  this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+  this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+  this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
 
   this->SetGlobalGenerator(cm::make_unique<cmGlobalGenerator>(this));
 
   cmStateSnapshot snapshot = this->GetCurrentSnapshot();
   snapshot.GetDirectory().SetCurrentBinary(
-    cmSystemTools::GetCurrentWorkingDirectory());
+    cmSystemTools::GetLogicalWorkingDirectory());
   snapshot.GetDirectory().SetCurrentSource(
-    cmSystemTools::GetCurrentWorkingDirectory());
+    cmSystemTools::GetLogicalWorkingDirectory());
   // read in the list file to fill the cache
   snapshot.SetDefaultDefinitions();
   auto mfu = cm::make_unique<cmMakefile>(this->GetGlobalGenerator(), snapshot);
@@ -1471,10 +1471,10 @@ void cmake::SetArgs(const std::vector<std::string>& args)
   }
 
   if (!haveSourceDir) {
-    this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+    this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
   }
   if (!haveBinaryDir) {
-    this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+    this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
   }
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -1839,12 +1839,12 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
       this->SetHomeDirectoryViaCommandLine(listPath);
       if (no_build_tree) {
         this->SetHomeOutputDirectory(
-          cmSystemTools::GetCurrentWorkingDirectory());
+          cmSystemTools::GetLogicalWorkingDirectory());
       }
     } else if (no_source_tree && no_build_tree) {
       this->SetHomeDirectory(listPath);
       this->SetHomeOutputDirectory(
-        cmSystemTools::GetCurrentWorkingDirectory());
+        cmSystemTools::GetLogicalWorkingDirectory());
     } else if (no_build_tree) {
       this->SetHomeOutputDirectory(listPath);
     }
@@ -1861,7 +1861,7 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
       // We didn't find a CMakeCache.txt and it wasn't specified
       // with -B. Assume the current working directory as the build tree.
       this->SetHomeOutputDirectory(
-        cmSystemTools::GetCurrentWorkingDirectory());
+        cmSystemTools::GetLogicalWorkingDirectory());
       used_provided_path = false;
     }
   }
@@ -3468,7 +3468,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
 {
   // so create the directory
   std::string resultFile;
-  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+  std::string cwd = cmSystemTools::GetLogicalWorkingDirectory();
   std::string destPath = cwd + "/__cmake_systeminformation";
   cmSystemTools::RemoveADirectory(destPath);
   if (!cmSystemTools::MakeDirectory(destPath)) {
@@ -3606,8 +3606,8 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
 
 #if !defined(CMAKE_BOOTSTRAP)
   if (!presetName.empty() || listPresets) {
-    this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
-    this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+    this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+    this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
 
     cmCMakePresetsGraph settingsFile;
     auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
@@ -3952,8 +3952,8 @@ int cmake::Workflow(const std::string& presetName,
                     WorkflowListPresets listPresets, WorkflowFresh fresh)
 {
 #ifndef CMAKE_BOOTSTRAP
-  this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
-  this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+  this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
+  this->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
 
   cmCMakePresetsGraph settingsFile;
   auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());

+ 1 - 1
Source/cmakemain.cxx

@@ -219,7 +219,7 @@ std::function<bool(std::string const& value)> getShowCachedCallback(
 
 int do_cmake(int ac, char const* const* av)
 {
-  if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
+  if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
     std::cerr << "Current working directory cannot be established."
               << std::endl;
     return 1;

+ 2 - 1
Source/cmcldeps.cxx

@@ -24,6 +24,7 @@
 #include <windows.h>
 
 #include "cmsys/Encoding.hxx"
+#include "cmsys/SystemTools.hxx"
 
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -151,7 +152,7 @@ static void outputDepFile(const std::string& dfile, const std::string& objfile,
   // FIXME should this be fatal or not? delete obj? delete d?
   if (!out)
     return;
-  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+  std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
   replaceAll(cwd, "/", "\\");
   cwd += "\\";
 

+ 1 - 1
Source/ctest.cxx

@@ -182,7 +182,7 @@ int main(int argc, char const* const* argv)
     return cmCTestLaunch::Main(argc, argv);
   }
 
-  if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
+  if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
     std::cerr << "Current working directory cannot be established.\n";
     return 1;
   }

+ 3 - 2
Tests/CMakeLib/testDebuggerAdapterPipe.cxx

@@ -20,9 +20,10 @@
 #include "cmVersionConfig.h"
 
 #ifdef _WIN32
+#  include "cmsys/SystemTools.hxx"
+
 #  include "cmCryptoHash.h"
 #  include "cmDebuggerWindowsPipeConnection.h"
-#  include "cmSystemTools.h"
 #else
 #  include "cmDebuggerPosixPipeConnection.h"
 #endif
@@ -69,7 +70,7 @@ bool testProtocolWithPipes()
 #ifdef _WIN32
   std::string namedPipe = R"(\\.\pipe\LOCAL\CMakeDebuggerPipe2_)" +
     cmCryptoHash(cmCryptoHash::AlgoSHA256)
-      .HashString(cmSystemTools::GetCurrentWorkingDirectory());
+      .HashString(cmsys::SystemTools::GetCurrentWorkingDirectory());
 #else
   std::string namedPipe = "CMakeDebuggerPipe2";
 #endif

+ 2 - 2
Tests/CMakeLib/testUVProcessChainHelper.cxx

@@ -7,7 +7,7 @@
 #include <string>
 #include <thread>
 
-#include "cmSystemTools.h"
+#include "cmsys/SystemTools.hxx"
 
 #ifdef _WIN32
 #  include <windows.h>
@@ -73,7 +73,7 @@ int main(int argc, char** argv)
 #endif
   }
   if (command == "pwd") {
-    std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+    std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
     std::cout << cwd << std::flush;
     return 0;
   }