cmFilePathChecksum.cxx 3.2 KB

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