cmSystemTools: Add GetLogicalWorkingDirectory

Track the current working directory with symbolic links preserved.
This commit is contained in:
Brad King 2024-10-28 11:21:24 -04:00
parent f9f4ab55ac
commit 5aed3ee49d
18 changed files with 85 additions and 53 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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 =

View File

@ -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);

View File

@ -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")) {

View File

@ -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()));
}
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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 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,

View File

@ -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,

View File

@ -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;

View File

@ -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());

View File

@ -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;

View File

@ -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 += "\\";

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}