From 8ec7408d745a9e17a1e35a4e97e9ab33044832c9 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Wed, 6 Jan 2021 13:52:53 +0100 Subject: Makefile dependencies: ensure long paths are used on Windows --- Source/cmGccDepfileReader.cxx | 23 ++++++++--------------- Source/cmGccDepfileReader.h | 6 ++---- Source/cmSystemTools.cxx | 24 ++++++++++++++++++++++++ Source/cmSystemTools.h | 6 ++++++ Source/cmcmd.cxx | 9 ++++----- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx index 96a562e..8253375 100644 --- a/Source/cmGccDepfileReader.cxx +++ b/Source/cmGccDepfileReader.cxx @@ -12,40 +12,33 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -cm::optional cmReadGccDepfile(const char* filePath) -{ - cmGccDepfileLexerHelper helper; - if (helper.readFile(filePath)) { - return cm::make_optional(std::move(helper).extractContent()); - } - return cm::nullopt; -} - cm::optional cmReadGccDepfile(const char* filePath, const std::string& prefix) { - auto deps = cmReadGccDepfile(filePath); - - if (prefix.empty() || !deps) { - return deps; + cmGccDepfileLexerHelper helper; + if (!helper.readFile(filePath)) { + return cm::nullopt; } + auto deps = cm::make_optional(std::move(helper).extractContent()); for (auto& dep : *deps) { for (auto& rule : dep.rules) { - if (!cmSystemTools::FileIsFullPath(rule)) { + if (!prefix.empty() && !cmSystemTools::FileIsFullPath(rule)) { rule = cmStrCat(prefix, rule); } if (cmSystemTools::FileIsFullPath(rule)) { rule = cmSystemTools::CollapseFullPath(rule); } + cmSystemTools::ConvertToLongPath(rule); } for (auto& path : dep.paths) { - if (!cmSystemTools::FileIsFullPath(path)) { + if (!prefix.empty() && !cmSystemTools::FileIsFullPath(path)) { path = cmStrCat(prefix, path); } if (cmSystemTools::FileIsFullPath(path)) { path = cmSystemTools::CollapseFullPath(path); } + cmSystemTools::ConvertToLongPath(path); } } diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h index 66ff75d..c8a3748 100644 --- a/Source/cmGccDepfileReader.h +++ b/Source/cmGccDepfileReader.h @@ -8,10 +8,8 @@ #include "cmGccDepfileReaderTypes.h" -cm::optional cmReadGccDepfile(const char* filePath); - /* * Read dependencies file and append prefix to all relative paths */ -cm::optional cmReadGccDepfile(const char* filePath, - const std::string& prefix); +cm::optional cmReadGccDepfile( + const char* filePath, const std::string& prefix = {}); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 6a705f4..024356f 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1255,6 +1255,30 @@ void cmSystemTools::ConvertToOutputSlashes(std::string& path) #endif } +void cmSystemTools::ConvertToLongPath(std::string& path) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + // Try to convert path to a long path only if the path contains character '~' + if (path.find('~') == std::string::npos) { + return; + } + + std::wstring wPath = cmsys::Encoding::ToWide(path); + DWORD ret = GetLongPathNameW(wPath.c_str(), nullptr, 0); + std::vector buffer(ret); + if (ret != 0) { + ret = GetLongPathNameW(wPath.c_str(), buffer.data(), + static_cast(buffer.size())); + } + + if (ret != 0) { + path = cmsys::Encoding::ToNarrow(buffer.data()); + } +#else + static_cast(path); +#endif +} + std::string cmSystemTools::ConvertToRunCommandPath(const std::string& path) { #if defined(_WIN32) && !defined(__CYGWIN__) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 1100f05..5bbbb0c 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -287,6 +287,12 @@ public: // running cmake needs paths to be in its format static std::string ConvertToRunCommandPath(const std::string& path); + /** + * For windows computes the long path for the given path, + * For Unix, it is a noop + */ + static void ConvertToLongPath(std::string& path); + /** compute the relative path from local to remote. local must be a directory. remote can be a file or a directory. Both remote and local must be full paths. Basically, if diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 4c0fbeb..851205e 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -231,11 +231,10 @@ private: bool ProcessLine() override { if (cmHasPrefix(this->Line, this->IncludePrefix)) { - this->DepFile << cmCMakePath( - cmTrimWhitespace(this->Line.c_str() + - this->IncludePrefix.size())) - .GenericString() - << std::endl; + auto path = + cmTrimWhitespace(this->Line.c_str() + this->IncludePrefix.size()); + cmSystemTools::ConvertToLongPath(path); + this->DepFile << cmCMakePath(path).GenericString() << std::endl; } else { this->Output << this->Line << std::endl << std::flush; } -- cgit v0.12