cmSystemTools: Add GetLogicalWorkingDirectory
Track the current working directory with symbolic links preserved.
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 68e759d..9979dfa 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -113,7 +113,7 @@
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 @@
// 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 @@
return 1;
}
- cmSystemTools::ChangeDirectory(expandedConfigurePreset->BinaryDir);
+ cmSystemTools::SetLogicalWorkingDirectory(
+ expandedConfigurePreset->BinaryDir);
auto presetEnvironment = expandedPreset->Environment;
for (auto const& var : presetEnvironment) {
@@ -408,7 +409,7 @@
if (!cpackConfigFile.empty()) {
cpackConfigFile = cmSystemTools::ToNormalizedPathOnDisk(cpackConfigFile);
} else {
- cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(),
+ cpackConfigFile = cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(),
"/CPackConfig.cmake");
cpackConfigFileSpecified = false;
}
@@ -488,7 +489,7 @@
cpackProjectDirectory = cmSystemTools::CollapseFullPath(*pd);
} else {
// Default to the current working directory.
- cpackProjectDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ cpackProjectDirectory = cmSystemTools::GetLogicalWorkingDirectory();
}
}
globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);
diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx
index 4b4e5c5..4156294 100644
--- a/Source/CTest/cmCTestLaunchReporter.cxx
+++ b/Source/CTest/cmCTestLaunchReporter.cxx
@@ -25,7 +25,7 @@
this->Passthru = true;
this->Status.Finished = true;
this->ExitCode = 1;
- this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
+ this->CWD = cmSystemTools::GetLogicalWorkingDirectory();
this->ComputeFileNames();
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 953f116..6c63c9d 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -188,7 +188,7 @@
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 =
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 7c4e2ea..f42d84e 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -128,7 +128,7 @@
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 @@
}
std::string fname =
- cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), '/', args[0]);
+ cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), '/', args[0]);
return ReadSubdirectory(std::move(fname), status);
}
@@ -354,7 +354,7 @@
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 @@
}
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 @@
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);
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index bc21cd0..8f7e515 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -101,7 +101,7 @@
}
}
- 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")) {
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 7847a4b..c3adae1 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -243,7 +243,7 @@
} else if (cmSystemTools::FileExists(srcFilePath.c_str())) {
dialog.setSourceDirectory(QString::fromStdString(filePath));
dialog.setBinaryDirectory(
- QString::fromStdString(cmSystemTools::GetCurrentWorkingDirectory()));
+ QString::fromStdString(cmSystemTools::GetLogicalWorkingDirectory()));
}
}
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 071c5f8..aa04d17 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -574,7 +574,7 @@
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 @@
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::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 @@
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);
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 9cb8d90..82847c4 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -3847,7 +3847,7 @@
if (!cmSystemTools::FileIsFullPath(inFile)) {
inFile =
- cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/", inFile);
+ cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), "/", inFile);
}
}
diff --git a/Source/cmInstallScriptHandler.cxx b/Source/cmInstallScriptHandler.cxx
index 9a4e70f..a7dfb0c 100644
--- a/Source/cmInstallScriptHandler.cxx
+++ b/Source/cmInstallScriptHandler.cxx
@@ -133,7 +133,7 @@
InstallScript::InstallScript(const std::vector<std::string>& cmd)
{
this->name = cmSystemTools::RelativePath(
- cmSystemTools::GetCurrentWorkingDirectory(), cmd.back());
+ cmSystemTools::GetLogicalWorkingDirectory(), cmd.back());
this->command = cmd;
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index dcd90bc..e06627f 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1916,12 +1916,12 @@
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 @@
#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 @@
return config;
}
-std::string cmSystemTools::GetCurrentWorkingDirectory()
+std::string const& cmSystemTools::GetLogicalWorkingDirectory()
{
- return cmSystemTools::ToNormalizedPathOnDisk(
- cmsys::SystemTools::GetCurrentWorkingDirectory());
+ return cmSystemToolsLogicalWorkingDirectory;
+}
+
+cmsys::Status cmSystemTools::SetLogicalWorkingDirectory(std::string const& lwd)
+{
+ cmsys::Status status = cmSystemTools::ChangeDirectory(lwd);
+ if (status) {
+ cmSystemToolsLogicalWorkingDirectory = lwd;
+ }
+ return status;
}
void cmSystemTools::MakefileColorEcho(int color, const char* message,
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 5c45cc7..06a8ce6 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -534,8 +534,11 @@
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,
diff --git a/Source/cmWorkingDirectory.cxx b/Source/cmWorkingDirectory.cxx
index 574699c..ec10fb1 100644
--- a/Source/cmWorkingDirectory.cxx
+++ b/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 @@
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;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index ffbf706..b2ba8d5 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -286,7 +286,7 @@
};
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 @@
// 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 @@
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 @@
}
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 @@
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 @@
// 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 @@
{
// 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 @@
#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 @@
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());
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index eb4f9f2..985362a 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -219,7 +219,7 @@
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;
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 5310166..aa4fd76 100644
--- a/Source/cmcldeps.cxx
+++ b/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 @@
// 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 += "\\";
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 481b80b..388e96b 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -182,7 +182,7 @@
return cmCTestLaunch::Main(argc, argv);
}
- if (cmSystemTools::GetCurrentWorkingDirectory().empty()) {
+ if (cmSystemTools::GetLogicalWorkingDirectory().empty()) {
std::cerr << "Current working directory cannot be established.\n";
return 1;
}
diff --git a/Tests/CMakeLib/testDebuggerAdapterPipe.cxx b/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
index 3647088..312b0e2 100644
--- a/Tests/CMakeLib/testDebuggerAdapterPipe.cxx
+++ b/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 @@
#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
diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx
index 1b4adb7..29ee765 100644
--- a/Tests/CMakeLib/testUVProcessChainHelper.cxx
+++ b/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 @@
#endif
}
if (command == "pwd") {
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
std::cout << cwd << std::flush;
return 0;
}