From 5910bf0b40607e00142f774b820dace3fac06d1f Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 7 Mar 2025 14:24:12 -0500 Subject: [PATCH] cmSystemTools: Restore GetRealPathResolvingWindowsSubst We need it to restore behavior on Windows. Revert commit 16af27fd42 (cmSystemTools: Drop GetRealPathResolvingWindowsSubst, 2024-11-04, v4.0.0-rc1~521^2), but with a cleaned up implementation. Issue: #26750 Issue: #18033 --- Source/cmSystemTools.cxx | 31 +++++++++++++++++++++++++++++++ Source/cmSystemTools.h | 6 ++++++ Source/cmTimestamp.cxx | 3 ++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 21f285c2e5..a0150e6a64 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1305,6 +1305,37 @@ bool FileModeGuard::HasErrors() const return filepath_.empty(); } +std::string cmSystemTools::GetRealPathResolvingWindowsSubst( + std::string const& path, std::string* errorMessage) +{ +#ifdef _WIN32 + // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found + std::string resolved_path; + uv_fs_t req; + int err = uv_fs_realpath(nullptr, &req, path.c_str(), nullptr); + if (!err) { + resolved_path = std::string((char*)req.ptr); + cmSystemTools::ConvertToUnixSlashes(resolved_path); + } else if (err == UV_ENOSYS) { + resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage); + } else if (errorMessage) { + cmsys::Status status = + cmsys::Status::Windows(uv_fs_get_system_error(&req)); + *errorMessage = status.GetString(); + resolved_path.clear(); + } else { + resolved_path = path; + } + // Normalize to upper-case drive letter as cm::PathResolver does. + if (resolved_path.size() > 1 && resolved_path[1] == ':') { + resolved_path[0] = toupper(resolved_path[0]); + } + return resolved_path; +#else + return cmsys::SystemTools::GetRealPath(path, errorMessage); +#endif +} + std::string cmSystemTools::GetRealPath(std::string const& path, std::string* errorMessage) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index d6967b65e3..16c5caa321 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -651,6 +651,12 @@ public: static std::string GetComspec(); #endif + /** Get the real path for a given path, removing all symlinks. + This variant of GetRealPath also works on Windows but will + resolve subst drives too. */ + static std::string GetRealPathResolvingWindowsSubst( + std::string const& path, std::string* errorMessage = nullptr); + /** Get the real path for a given path, removing all symlinks. */ static std::string GetRealPath(std::string const& path, std::string* errorMessage = nullptr); diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index d7de0919a1..fdeff04a51 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -62,7 +62,8 @@ std::string cmTimestamp::FileModificationTime(char const* path, std::string const& formatString, bool utcFlag) const { - std::string real_path = cmSystemTools::GetRealPath(path); + std::string real_path = + cmSystemTools::GetRealPathResolvingWindowsSubst(path); if (!cmsys::SystemTools::FileExists(real_path)) { return std::string();