cmFilePathChecksum.cxx 3.2 KB

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