summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CMakeLists.txt4
-rw-r--r--Source/cmFilePathChecksum.cxx88
-rw-r--r--Source/cmFilePathChecksum.h65
-rw-r--r--Source/cmFilePathUuid.cxx118
-rw-r--r--Source/cmFilePathUuid.h69
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx40
-rw-r--r--Source/cmQtAutoGenerators.cxx47
-rw-r--r--Source/cmQtAutoGenerators.h3
8 files changed, 205 insertions, 229 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 5b381b4..d15fdbe 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -243,8 +243,8 @@ set(SRCS
cmFileLockPool.h
cmFileLockResult.cxx
cmFileLockResult.h
- cmFilePathUuid.cxx
- cmFilePathUuid.h
+ cmFilePathChecksum.cxx
+ cmFilePathChecksum.h
cmFileTimeComparison.cxx
cmFileTimeComparison.h
cmFortranLexer.cxx
diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx
new file mode 100644
index 0000000..3d8b695
--- /dev/null
+++ b/Source/cmFilePathChecksum.cxx
@@ -0,0 +1,88 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFilePathChecksum.h"
+
+#include "cmBase32.h"
+#include "cmCryptoHash.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+
+#include <vector>
+
+cmFilePathChecksum::cmFilePathChecksum()
+{
+}
+
+cmFilePathChecksum::cmFilePathChecksum(const std::string& currentSrcDir,
+ const std::string& currentBinDir,
+ const std::string& projectSrcDir,
+ const std::string& projectBinDir)
+{
+ setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir);
+}
+
+cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile)
+{
+ setupParentDirs(makefile->GetCurrentSourceDirectory(),
+ makefile->GetCurrentBinaryDirectory(),
+ makefile->GetHomeDirectory(),
+ makefile->GetHomeOutputDirectory());
+}
+
+void cmFilePathChecksum::setupParentDirs(const std::string& currentSrcDir,
+ const std::string& currentBinDir,
+ const std::string& projectSrcDir,
+ const std::string& projectBinDir)
+{
+ parentDirs[0].first = cmsys::SystemTools::GetRealPath(currentSrcDir);
+ parentDirs[1].first = cmsys::SystemTools::GetRealPath(currentBinDir);
+ parentDirs[2].first = cmsys::SystemTools::GetRealPath(projectSrcDir);
+ parentDirs[3].first = cmsys::SystemTools::GetRealPath(projectBinDir);
+
+ parentDirs[0].second = "CurrentSource";
+ parentDirs[1].second = "CurrentBinary";
+ parentDirs[2].second = "ProjectSource";
+ parentDirs[3].second = "ProjectBinary";
+}
+
+std::string cmFilePathChecksum::get(const std::string& filePath)
+{
+ std::string relPath;
+ std::string relSeed;
+ {
+ const std::string fileReal = cmsys::SystemTools::GetRealPath(filePath);
+ std::string parentDir;
+ // Find closest project parent directory
+ for (size_t ii = 0; ii != numParentDirs; ++ii) {
+ const std::string& pDir = parentDirs[ii].first;
+ if (!pDir.empty() &&
+ cmsys::SystemTools::IsSubDirectory(fileReal, pDir)) {
+ relSeed = parentDirs[ii].second;
+ parentDir = pDir;
+ break;
+ }
+ }
+ // Use file system root as fallback parent directory
+ if (parentDir.empty()) {
+ relSeed = "FileSystemRoot";
+ cmsys::SystemTools::SplitPathRootComponent(fileReal, &parentDir);
+ }
+ // Calculate relative path from project parent directory
+ relPath = cmsys::SystemTools::RelativePath(
+ parentDir, cmsys::SystemTools::GetParentDirectory(fileReal));
+ }
+
+ // Calculate the file ( seed + relative path ) binary checksum
+ std::vector<unsigned char> hashBytes =
+ cmCryptoHash(cmCryptoHash::AlgoSHA256).ByteHashString(relSeed + relPath);
+
+ // Convert binary checksum to string
+ return cmBase32Encoder().encodeString(&hashBytes[0], hashBytes.size(),
+ false);
+}
+
+std::string cmFilePathChecksum::getPart(const std::string& filePath,
+ size_t length)
+{
+ return get(filePath).substr(0, length);
+}
diff --git a/Source/cmFilePathChecksum.h b/Source/cmFilePathChecksum.h
new file mode 100644
index 0000000..df19053
--- /dev/null
+++ b/Source/cmFilePathChecksum.h
@@ -0,0 +1,65 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmFilePathChecksum_h
+#define cmFilePathChecksum_h
+
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include <stddef.h>
+#include <string>
+#include <utility>
+
+class cmMakefile;
+
+/** \class cmFilePathChecksum
+ * @brief Generates a checksum for the parent directory of a file
+ *
+ * The checksum is calculated from the relative file path to the
+ * closest known project directory. This guarantees reproducibility
+ * when source and build directory differ e.g. for different project
+ * build directories.
+ */
+class cmFilePathChecksum
+{
+public:
+ /// Maximum number of characters to use from the path checksum
+ static const size_t partLengthDefault = 10;
+
+ /// @brief Parent directories are empty
+ cmFilePathChecksum();
+
+ /// @brief Initilizes the parent directories manually
+ cmFilePathChecksum(const std::string& currentSrcDir,
+ const std::string& currentBinDir,
+ const std::string& projectSrcDir,
+ const std::string& projectBinDir);
+
+ /// @brief Initilizes the parent directories from a makefile
+ cmFilePathChecksum(cmMakefile* makefile);
+
+ /// @brief Allows parent directories setup after construction
+ ///
+ void setupParentDirs(const std::string& currentSrcDir,
+ const std::string& currentBinDir,
+ const std::string& projectSrcDir,
+ const std::string& projectBinDir);
+
+ /* @brief Calculates the path checksum for the parent directory of a file
+ *
+ */
+ std::string get(const std::string& filePath);
+
+ /* @brief Same as get() but returns only the first length characters
+ *
+ */
+ std::string getPart(const std::string& filePath,
+ size_t length = partLengthDefault);
+
+private:
+ /// Size of the parent directory list
+ static const size_t numParentDirs = 4;
+ /// List of (directory name, seed name) pairs
+ std::pair<std::string, std::string> parentDirs[numParentDirs];
+};
+
+#endif
diff --git a/Source/cmFilePathUuid.cxx b/Source/cmFilePathUuid.cxx
deleted file mode 100644
index 03d2524..0000000
--- a/Source/cmFilePathUuid.cxx
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmFilePathUuid.h"
-
-#include "cmBase32.h"
-#include "cmCryptoHash.h"
-#include "cmMakefile.h"
-#include "cmSystemTools.h"
-
-#include <vector>
-
-cmFilePathUuid::cmFilePathUuid(cmMakefile* makefile)
-{
- initParentDirs(makefile->GetCurrentSourceDirectory(),
- makefile->GetCurrentBinaryDirectory(),
- makefile->GetHomeDirectory(),
- makefile->GetHomeOutputDirectory());
-}
-
-cmFilePathUuid::cmFilePathUuid(const std::string& currentSrcDir,
- const std::string& currentBinDir,
- const std::string& projectSrcDir,
- const std::string& projectBinDir)
-{
- initParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir);
-}
-
-void cmFilePathUuid::initParentDirs(const std::string& currentSrcDir,
- const std::string& currentBinDir,
- const std::string& projectSrcDir,
- const std::string& projectBinDir)
-{
- parentDirs[0].first = cmsys::SystemTools::GetRealPath(currentSrcDir);
- parentDirs[1].first = cmsys::SystemTools::GetRealPath(currentBinDir);
- parentDirs[2].first = cmsys::SystemTools::GetRealPath(projectSrcDir);
- parentDirs[3].first = cmsys::SystemTools::GetRealPath(projectBinDir);
-
- parentDirs[0].second = "CurrentSource";
- parentDirs[1].second = "CurrentBinary";
- parentDirs[2].second = "ProjectSource";
- parentDirs[3].second = "ProjectBinary";
-}
-
-std::string cmFilePathUuid::get(const std::string& filePath,
- const char* outputPrefix,
- const char* outputSuffix)
-{
- std::string sourceFilename = cmsys::SystemTools::GetFilenameName(filePath);
- std::string sourceBasename =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(sourceFilename);
-
- // Acquire checksum string
- std::string checksum;
- {
- std::string sourceRelPath;
- std::string sourceRelSeed;
- GetRelPathSeed(filePath, sourceRelPath, sourceRelSeed);
- checksum = GetChecksumString(sourceFilename, sourceRelPath, sourceRelSeed);
- }
-
- // Compose the file name
- std::string uuid;
- if (outputPrefix) {
- uuid += outputPrefix;
- }
- uuid += sourceBasename.substr(0, partLengthName);
- uuid += "_";
- uuid += checksum.substr(0, partLengthCheckSum);
- if (outputSuffix) {
- uuid += outputSuffix;
- }
- return uuid;
-}
-
-void cmFilePathUuid::GetRelPathSeed(const std::string& filePath,
- std::string& sourceRelPath,
- std::string& sourceRelSeed)
-{
- const std::string sourceNameReal = cmsys::SystemTools::GetRealPath(filePath);
- std::string parentDirectory;
- // Find closest project parent directory
- for (size_t ii = 0; ii != numParentDirs; ++ii) {
- const std::string& pDir = parentDirs[ii].first;
- if (!pDir.empty() &&
- cmsys::SystemTools::IsSubDirectory(sourceNameReal, pDir)) {
- sourceRelSeed = parentDirs[ii].second;
- parentDirectory = pDir;
- break;
- }
- }
- // Check if the file path is below a known project directory
- if (parentDirectory.empty()) {
- // Use file syste root as fallback parent directory
- sourceRelSeed = "FileSystemRoot";
- cmsys::SystemTools::SplitPathRootComponent(sourceNameReal,
- &parentDirectory);
- }
- sourceRelPath = cmsys::SystemTools::RelativePath(
- parentDirectory, cmsys::SystemTools::GetParentDirectory(sourceNameReal));
-}
-
-std::string cmFilePathUuid::GetChecksumString(
- const std::string& sourceFilename, const std::string& sourceRelPath,
- const std::string& sourceRelSeed)
-{
- std::string checksumBase32;
- {
- // Calculate the file ( seed + relative path + name ) checksum
- std::vector<unsigned char> hashBytes =
- cmCryptoHash(cmCryptoHash::AlgoSHA256)
- .ByteHashString(sourceRelSeed + sourceRelPath + sourceFilename);
-
- checksumBase32 =
- cmBase32Encoder().encodeString(&hashBytes[0], hashBytes.size(), false);
- }
-
- return checksumBase32;
-}
diff --git a/Source/cmFilePathUuid.h b/Source/cmFilePathUuid.h
deleted file mode 100644
index a450526..0000000
--- a/Source/cmFilePathUuid.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmFilePathUuid_h
-#define cmFilePathUuid_h
-
-#include <cmConfigure.h> // IWYU pragma: keep
-
-#include <stddef.h>
-#include <string>
-#include <utility>
-
-class cmMakefile;
-
-/** \class cmFilePathUuid
- * @brief Generates a unique pathless file name with a checksum component
- * calculated from the file path.
- *
- * The checksum is calculated from the relative file path to the
- * closest known project directory. This guarantees reproducibility
- * when source and build directory differ e.g. for different project
- * build directories.
- */
-class cmFilePathUuid
-{
-public:
- /// Maximum number of characters to use from the file name
- static const size_t partLengthName = 14;
- /// Maximum number of characters to use from the path checksum
- static const size_t partLengthCheckSum = 14;
-
- /// @brief Initilizes the parent directories from a makefile
- cmFilePathUuid(cmMakefile* makefile);
-
- /// @brief Initilizes the parent directories manually
- cmFilePathUuid(const std::string& currentSrcDir,
- const std::string& currentBinDir,
- const std::string& projectSrcDir,
- const std::string& projectBinDir);
-
- /* @brief Calculates and returns the uuid for a file path
- *
- * @arg outputPrefix optional string to prepend to the result
- * @arg outputSuffix optional string to append to the result
- */
- std::string get(const std::string& filePath,
- const char* outputPrefix = CM_NULLPTR,
- const char* outputSuffix = CM_NULLPTR);
-
-private:
- void initParentDirs(const std::string& currentSrcDir,
- const std::string& currentBinDir,
- const std::string& projectSrcDir,
- const std::string& projectBinDir);
-
- /// Returns the relative path and the parent directory key string (seed)
- void GetRelPathSeed(const std::string& filePath, std::string& sourceRelPath,
- std::string& sourceRelSeed);
-
- std::string GetChecksumString(const std::string& sourceFilename,
- const std::string& sourceRelPath,
- const std::string& sourceRelSeed);
-
- /// Size of the parent directory list
- static const size_t numParentDirs = 4;
- /// List of (directory name, seed name) pairs
- std::pair<std::string, std::string> parentDirs[numParentDirs];
-};
-
-#endif
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index e589a5a..9766a5a 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -4,7 +4,7 @@
#include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
-#include "cmFilePathUuid.h"
+#include "cmFilePathChecksum.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -96,7 +96,7 @@ static void SetupSourceFiles(cmGeneratorTarget const* target,
std::vector<std::string> newRccFiles;
- cmFilePathUuid fpathUuid(makefile);
+ cmFilePathChecksum fpathCheckSum(makefile);
for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
fileIt != srcFiles.end(); ++fileIt) {
cmSourceFile* sf = *fileIt;
@@ -115,15 +115,21 @@ static void SetupSourceFiles(cmGeneratorTarget const* target,
if (ext == "qrc" &&
!cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) {
- std::string rcc_output_file = GetAutogenTargetBuildDir(target);
- // Create output directory
- cmSystemTools::MakeDirectory(rcc_output_file.c_str());
- rcc_output_file += fpathUuid.get(absFile, "qrc_", ".cpp");
+ std::string rccOutputFile = GetAutogenTargetBuildDir(target);
+ rccOutputFile += fpathCheckSum.getPart(absFile);
+ rccOutputFile += "/qrc_";
+ rccOutputFile +=
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+ rccOutputFile += ".cpp";
makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
- rcc_output_file.c_str(), false);
- makefile->GetOrCreateSource(rcc_output_file, true);
- newRccFiles.push_back(rcc_output_file);
+ rccOutputFile.c_str(), false);
+ makefile->GetOrCreateSource(rccOutputFile, true);
+ newRccFiles.push_back(rccOutputFile);
+
+ // Create output directory
+ cmSystemTools::MakeDirectory(
+ cmsys::SystemTools::GetFilenamePath(rccOutputFile));
}
}
@@ -755,9 +761,9 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
#endif
) {
if (target->GetPropertyAsBool("AUTORCC")) {
+ cmFilePathChecksum fpathCheckSum(makefile);
std::vector<cmSourceFile*> srcFiles;
target->GetConfigCommonSourceFiles(srcFiles);
- cmFilePathUuid fpathUuid(makefile);
for (std::vector<cmSourceFile*>::const_iterator fileIt =
srcFiles.begin();
fileIt != srcFiles.end(); ++fileIt) {
@@ -767,11 +773,17 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
{
const std::string absFile =
cmsys::SystemTools::GetRealPath(sf->GetFullPath());
- std::string rcc_output_file = GetAutogenTargetBuildDir(target);
+
+ std::string rccOutputFile = GetAutogenTargetBuildDir(target);
+ rccOutputFile += fpathCheckSum.getPart(absFile);
+ rccOutputFile += "/qrc_";
+ rccOutputFile +=
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile);
+ rccOutputFile += ".cpp";
+ rcc_output.push_back(rccOutputFile);
// Create output directory
- cmSystemTools::MakeDirectory(rcc_output_file.c_str());
- rcc_output_file += fpathUuid.get(absFile, "qrc_", ".cpp");
- rcc_output.push_back(rcc_output_file);
+ cmSystemTools::MakeDirectory(
+ cmsys::SystemTools::GetFilenamePath(rccOutputFile));
}
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
RccListInputs(qtMajorVersion, sf, target, depends);
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index bd01d50..bb18e2e 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -15,7 +15,6 @@
#include <utility>
#include "cmAlgorithms.h"
-#include "cmFilePathUuid.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -397,6 +396,11 @@ void cmQtAutoGenerators::Init()
this->OutMocCppFilenameAbs = this->Builddir + this->OutMocCppFilenameRel;
+ // Init file path checksum generator
+ fpathCheckSum.setupParentDirs(this->Srcdir, this->Builddir,
+ this->ProjectSourceDir,
+ this->ProjectBinaryDir);
+
std::vector<std::string> cdefList;
cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList);
for (std::vector<std::string>::const_iterator it = cdefList.begin();
@@ -967,8 +971,6 @@ void cmQtAutoGenerators::ParseHeaders(
std::map<std::string, std::string>& notIncludedMocs,
std::map<std::string, std::vector<std::string> >& includedUis)
{
- cmFilePathUuid fpathUuid(this->Srcdir, this->Builddir,
- this->ProjectSourceDir, this->ProjectBinaryDir);
for (std::set<std::string>::const_iterator hIt = absHeaders.begin();
hIt != absHeaders.end(); ++hIt) {
const std::string& headerName = *hIt;
@@ -984,8 +986,10 @@ void cmQtAutoGenerators::ParseHeaders(
std::string macroName;
if (requiresMocing(contents, macroName)) {
- notIncludedMocs[headerName] =
- this->TargetBuildSubDir + fpathUuid.get(headerName, "moc_", ".cpp");
+ notIncludedMocs[headerName] = this->TargetBuildSubDir +
+ fpathCheckSum.getPart(headerName) + "/moc_" +
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(headerName) +
+ ".cpp";
}
}
this->ParseForUic(headerName, contents, includedUis);
@@ -1318,18 +1322,13 @@ bool cmQtAutoGenerators::GenerateQrcFiles()
{
// generate single map with input / output names
std::map<std::string, std::string> qrcGenMap;
- {
- cmFilePathUuid fpathUuid(this->Srcdir, this->Builddir,
- this->ProjectSourceDir, this->ProjectBinaryDir);
- for (std::vector<std::string>::const_iterator si =
- this->RccSources.begin();
- si != this->RccSources.end(); ++si) {
- const std::string ext =
- cmsys::SystemTools::GetFilenameLastExtension(*si);
- if (ext == ".qrc") {
- qrcGenMap[*si] =
- (this->TargetBuildSubDir + fpathUuid.get(*si, "qrc_", ".cpp"));
- }
+ for (std::vector<std::string>::const_iterator si = this->RccSources.begin();
+ si != this->RccSources.end(); ++si) {
+ const std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si);
+ if (ext == ".qrc") {
+ qrcGenMap[*si] = this->TargetBuildSubDir + fpathCheckSum.getPart(*si) +
+ "/qrc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(*si) +
+ ".cpp";
}
}
@@ -1368,15 +1367,11 @@ bool cmQtAutoGenerators::GenerateQrc(const std::string& qrcInputFile,
const std::string& qrcOutputFile,
bool unique_n)
{
- std::string symbolName;
- if (unique_n) {
- symbolName =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(qrcInputFile);
- } else {
- symbolName =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(qrcOutputFile);
- // Remove "qrc_" at string begin
- symbolName.erase(0, 4);
+ std::string symbolName =
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(qrcInputFile);
+ if (!unique_n) {
+ symbolName += "_";
+ symbolName += fpathCheckSum.getPart(qrcInputFile);
}
// Replace '-' with '_'. The former is valid for
// file names but not for symbol names.
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 466acb2..302c9be 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -4,6 +4,7 @@
#define cmQtAutoGenerators_h
#include <cmConfigure.h> // IWYU pragma: keep
+#include <cmFilePathChecksum.h>
#include <list>
#include <map>
@@ -130,6 +131,8 @@ private:
std::map<std::string, std::string> RccOptions;
std::map<std::string, std::vector<std::string> > RccInputs;
+ cmFilePathChecksum fpathCheckSum;
+
bool IncludeProjectDirsBefore;
bool Verbose;
bool ColorOutput;