1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmFilePathChecksum.h"
8 #include "cmCryptoHash.h"
9 #include "cmMakefile.h"
10 #include "cmSystemTools.h"
12 cmFilePathChecksum::cmFilePathChecksum() = default;
14 cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir,
15 std::string const& currentBinDir,
16 std::string const& projectSrcDir,
17 std::string const& projectBinDir)
19 this->setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir,
23 cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile)
25 this->setupParentDirs(makefile->GetCurrentSourceDirectory(),
26 makefile->GetCurrentBinaryDirectory(),
27 makefile->GetHomeDirectory(),
28 makefile->GetHomeOutputDirectory());
31 void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir,
32 std::string const& currentBinDir,
33 std::string const& projectSrcDir,
34 std::string const& projectBinDir)
36 this->parentDirs[0].first = cmSystemTools::GetRealPath(currentSrcDir);
37 this->parentDirs[1].first = cmSystemTools::GetRealPath(currentBinDir);
38 this->parentDirs[2].first = cmSystemTools::GetRealPath(projectSrcDir);
39 this->parentDirs[3].first = cmSystemTools::GetRealPath(projectBinDir);
41 this->parentDirs[0].second = "CurrentSource";
42 this->parentDirs[1].second = "CurrentBinary";
43 this->parentDirs[2].second = "ProjectSource";
44 this->parentDirs[3].second = "ProjectBinary";
47 std::string cmFilePathChecksum::get(std::string const& filePath) const
52 std::string const fileReal = cmSystemTools::GetRealPath(filePath);
53 std::string parentDir;
54 // Find closest project parent directory
55 for (auto const& pDir : this->parentDirs) {
56 if (!pDir.first.empty() &&
57 cmsys::SystemTools::IsSubDirectory(fileReal, pDir.first)) {
58 parentDir = pDir.first;
59 relSeed = pDir.second;
63 // Use file system root as fallback parent directory
64 if (parentDir.empty()) {
65 relSeed = "FileSystemRoot";
66 cmsys::SystemTools::SplitPathRootComponent(fileReal, &parentDir);
68 // Calculate relative path from project parent directory
69 relPath = cmsys::SystemTools::RelativePath(
70 parentDir, cmsys::SystemTools::GetParentDirectory(fileReal));
73 // Calculate the file ( seed + relative path ) binary checksum
74 std::vector<unsigned char> hashBytes =
75 cmCryptoHash(cmCryptoHash::AlgoSHA256).ByteHashString(relSeed + relPath);
77 // Convert binary checksum to string
78 return cmBase32Encoder().encodeString(hashBytes.data(), hashBytes.size(),
82 std::string cmFilePathChecksum::getPart(std::string const& filePath,
85 return this->get(filePath).substr(0, length);