| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file Copyright.txt or https://cmake.org/licensing for details. */ | |
| #include "cmFilePathChecksum.h" | |
| #include <vector> | |
| #include "cmBase32.h" | |
| #include "cmCryptoHash.h" | |
| #include "cmMakefile.h" | |
| #include "cmSystemTools.h" | |
| cmFilePathChecksum::cmFilePathChecksum() = default; | |
| cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir, | |
| std::string const& currentBinDir, | |
| std::string const& projectSrcDir, | |
| std::string const& projectBinDir) | |
| { | |
| this->setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, | |
| projectBinDir); | |
| } | |
| cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile) | |
| { | |
| this->setupParentDirs(makefile->GetCurrentSourceDirectory(), | |
| makefile->GetCurrentBinaryDirectory(), | |
| makefile->GetHomeDirectory(), | |
| makefile->GetHomeOutputDirectory()); | |
| } | |
| void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir, | |
| std::string const& currentBinDir, | |
| std::string const& projectSrcDir, | |
| std::string const& projectBinDir) | |
| { | |
| this->parentDirs[0].first = cmSystemTools::GetRealPath(currentSrcDir); | |
| this->parentDirs[1].first = cmSystemTools::GetRealPath(currentBinDir); | |
| this->parentDirs[2].first = cmSystemTools::GetRealPath(projectSrcDir); | |
| this->parentDirs[3].first = cmSystemTools::GetRealPath(projectBinDir); | |
| this->parentDirs[0].second = "CurrentSource"; | |
| this->parentDirs[1].second = "CurrentBinary"; | |
| this->parentDirs[2].second = "ProjectSource"; | |
| this->parentDirs[3].second = "ProjectBinary"; | |
| } | |
| std::string cmFilePathChecksum::get(std::string const& filePath) const | |
| { | |
| std::string relPath; | |
| std::string relSeed; | |
| { | |
| std::string const fileReal = cmSystemTools::GetRealPath(filePath); | |
| std::string parentDir; | |
| // Find closest project parent directory | |
| for (auto const& pDir : this->parentDirs) { | |
| if (!pDir.first.empty() && | |
| cmsys::SystemTools::IsSubDirectory(fileReal, pDir.first)) { | |
| parentDir = pDir.first; | |
| relSeed = pDir.second; | |
| break; | |
| } | |
| } | |
| // Use file system root as fallback parent directory | |
| if (parentDir.empty()) { | |
| relSeed = "FileSystemRoot"; | |
| cmsys::SystemTools::SplitPathRootComponent(fileReal, &parentDir); | |
| } | |
| // Calculate relative path from project parent directory | |
| relPath = cmsys::SystemTools::RelativePath( | |
| parentDir, cmsys::SystemTools::GetParentDirectory(fileReal)); | |
| } | |
| // Calculate the file ( seed + relative path ) binary checksum | |
| std::vector<unsigned char> hashBytes = | |
| cmCryptoHash(cmCryptoHash::AlgoSHA256).ByteHashString(relSeed + relPath); | |
| // Convert binary checksum to string | |
| return cmBase32Encoder().encodeString(hashBytes.data(), hashBytes.size(), | |
| false); | |
| } | |
| std::string cmFilePathChecksum::getPart(std::string const& filePath, | |
| size_t length) const | |
| { | |
| return this->get(filePath).substr(0, length); | |
| } |