cmFilePathChecksum.cxx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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"
  4. #include "cmBase32.h"
  5. #include "cmCryptoHash.h"
  6. #include "cmMakefile.h"
  7. #include "cmSystemTools.h"
  8. #include <vector>
  9. cmFilePathChecksum::cmFilePathChecksum()
  10. {
  11. }
  12. cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir,
  13. std::string const& currentBinDir,
  14. std::string const& projectSrcDir,
  15. std::string const& projectBinDir)
  16. {
  17. setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir);
  18. }
  19. cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile)
  20. {
  21. setupParentDirs(makefile->GetCurrentSourceDirectory(),
  22. makefile->GetCurrentBinaryDirectory(),
  23. makefile->GetHomeDirectory(),
  24. makefile->GetHomeOutputDirectory());
  25. }
  26. void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir,
  27. std::string const& currentBinDir,
  28. std::string const& projectSrcDir,
  29. std::string const& projectBinDir)
  30. {
  31. this->parentDirs[0].first = cmSystemTools::GetRealPath(currentSrcDir);
  32. this->parentDirs[1].first = cmSystemTools::GetRealPath(currentBinDir);
  33. this->parentDirs[2].first = cmSystemTools::GetRealPath(projectSrcDir);
  34. this->parentDirs[3].first = cmSystemTools::GetRealPath(projectBinDir);
  35. this->parentDirs[0].second = "CurrentSource";
  36. this->parentDirs[1].second = "CurrentBinary";
  37. this->parentDirs[2].second = "ProjectSource";
  38. this->parentDirs[3].second = "ProjectBinary";
  39. }
  40. std::string cmFilePathChecksum::get(std::string const& filePath) const
  41. {
  42. std::string relPath;
  43. std::string relSeed;
  44. {
  45. std::string const fileReal = cmSystemTools::GetRealPath(filePath);
  46. std::string parentDir;
  47. // Find closest project parent directory
  48. for (auto const& pDir : this->parentDirs) {
  49. if (!pDir.first.empty() &&
  50. cmsys::SystemTools::IsSubDirectory(fileReal, pDir.first)) {
  51. parentDir = pDir.first;
  52. relSeed = pDir.second;
  53. break;
  54. }
  55. }
  56. // Use file system root as fallback parent directory
  57. if (parentDir.empty()) {
  58. relSeed = "FileSystemRoot";
  59. cmsys::SystemTools::SplitPathRootComponent(fileReal, &parentDir);
  60. }
  61. // Calculate relative path from project parent directory
  62. relPath = cmsys::SystemTools::RelativePath(
  63. parentDir, cmsys::SystemTools::GetParentDirectory(fileReal));
  64. }
  65. // Calculate the file ( seed + relative path ) binary checksum
  66. std::vector<unsigned char> hashBytes =
  67. cmCryptoHash(cmCryptoHash::AlgoSHA256).ByteHashString(relSeed + relPath);
  68. // Convert binary checksum to string
  69. return cmBase32Encoder().encodeString(&hashBytes.front(), hashBytes.size(),
  70. false);
  71. }
  72. std::string cmFilePathChecksum::getPart(std::string const& filePath,
  73. size_t length) const
  74. {
  75. return get(filePath).substr(0, length);
  76. }