cmFilePathChecksum.cxx 3.1 KB

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