diff options
author | Brad King <brad.king@kitware.com> | 2019-03-19 12:55:09 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-03-19 12:55:18 (GMT) |
commit | 0587c4b247626cda58e55f3bdc0adc8c09ac8e16 (patch) | |
tree | e829e85d5b62328ed042c5f4e8a9d0f72a15f2be /Source | |
parent | 146b95949194ccf9aff3cfbe2243bde9727e16d5 (diff) | |
parent | ec3c968de27d0d352dce53e3400a33b1bc576496 (diff) | |
download | CMake-0587c4b247626cda58e55f3bdc0adc8c09ac8e16.zip CMake-0587c4b247626cda58e55f3bdc0adc8c09ac8e16.tar.gz CMake-0587c4b247626cda58e55f3bdc0adc8c09ac8e16.tar.bz2 |
Merge topic 'file_time_comparison'
ec3c968de2 cmake: Use scopes to limit temporary object lifetime
1de0c827a1 cmDependsC: Read cache file modification time only once
5536cec46e Rename cmFileTimeCache::FileTimeCompare to cmFileTimeCache::Compare
98d4846953 Rename cmFileTimeCache::FileTimesDiffer to cmFileTimeCache::DifferS
a6d75a1ce0 Substitute FileComparison in variable names with FileTimeCache
216416219a Rename cmFileTimeComparison to cmFileTimeCache
3160258393 cmFileTimeComparison: Replace anonymous private class with std::map
103aa9e46a cmFileTimeComparison: Use cmFileTime internally
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Brad King <brad.king@kitware.com>
Merge-request: !3101
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 8 | ||||
-rw-r--r-- | Source/CTest/cmCTestBuildHandler.cxx | 10 | ||||
-rw-r--r-- | Source/cmDepends.cxx | 9 | ||||
-rw-r--r-- | Source/cmDepends.h | 9 | ||||
-rw-r--r-- | Source/cmDependsC.cxx | 12 | ||||
-rw-r--r-- | Source/cmFileCopier.cxx | 2 | ||||
-rw-r--r-- | Source/cmFileCopier.h | 4 | ||||
-rw-r--r-- | Source/cmFileTime.cxx | 49 | ||||
-rw-r--r-- | Source/cmFileTime.h | 130 | ||||
-rw-r--r-- | Source/cmFileTimeCache.cxx | 57 | ||||
-rw-r--r-- | Source/cmFileTimeCache.h | 51 | ||||
-rw-r--r-- | Source/cmFileTimeComparison.cxx | 233 | ||||
-rw-r--r-- | Source/cmFileTimeComparison.h | 45 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator3.cxx | 17 | ||||
-rw-r--r-- | Source/cmake.cxx | 43 | ||||
-rw-r--r-- | Source/cmake.h | 6 |
16 files changed, 348 insertions, 337 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 696826f..596c7f5 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -236,8 +236,10 @@ set(SRCS cmFileLockResult.h cmFilePathChecksum.cxx cmFilePathChecksum.h - cmFileTimeComparison.cxx - cmFileTimeComparison.h + cmFileTime.cxx + cmFileTime.h + cmFileTimeCache.cxx + cmFileTimeCache.h cmFortranParserImpl.cxx cmFSPermissions.cxx cmFSPermissions.h @@ -796,7 +798,7 @@ foreach(check else() set(CMake_${check} 0) endif() - set_property(SOURCE cmFileTimeComparison.cxx APPEND PROPERTY + set_property(SOURCE cmFileTime.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMake_${check}=${CMake_${check}}) endforeach() diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 07bc7e7..8ea9a83 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -5,7 +5,7 @@ #include "cmAlgorithms.h" #include "cmCTest.h" #include "cmDuration.h" -#include "cmFileTimeComparison.h" +#include "cmFileTimeCache.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" #include "cmProcessOutput.h" @@ -503,7 +503,7 @@ void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml) class cmCTestBuildHandler::FragmentCompare { public: - FragmentCompare(cmFileTimeComparison* ftc) + FragmentCompare(cmFileTimeCache* ftc) : FTC(ftc) { } @@ -513,14 +513,14 @@ public: // Order files by modification time. Use lexicographic order // among files with the same time. int result; - if (this->FTC->FileTimeCompare(l, r, &result) && result != 0) { + if (this->FTC->Compare(l, r, &result) && result != 0) { return result < 0; } return l < r; } private: - cmFileTimeComparison* FTC = nullptr; + cmFileTimeCache* FTC = nullptr; }; void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml) @@ -530,7 +530,7 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml) } // Sort XML fragments in chronological order. - cmFileTimeComparison ftc; + cmFileTimeCache ftc; FragmentCompare fragmentCompare(&ftc); typedef std::set<std::string, FragmentCompare> Fragments; Fragments fragments(fragmentCompare); diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index c128b02..efadaf1 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmDepends.h" -#include "cmFileTimeComparison.h" +#include "cmFileTimeCache.h" #include "cmGeneratedFileStream.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" @@ -177,8 +177,7 @@ bool cmDepends::CheckDependencies( if (dependerExists) { // The dependee and depender both exist. Compare file times. int result = 0; - if ((!this->FileComparison->FileTimeCompare(depender, dependee, - &result) || + if ((!this->FileTimeCache->Compare(depender, dependee, &result) || result < 0)) { // The depender is older than the dependee. regenerate = true; @@ -195,8 +194,8 @@ bool cmDepends::CheckDependencies( // The dependee exists, but the depender doesn't. Regenerate if the // internalDepends file is older than the dependee. int result = 0; - if ((!this->FileComparison->FileTimeCompare(internalDependsFileName, - dependee, &result) || + if ((!this->FileTimeCache->Compare(internalDependsFileName, dependee, + &result) || result < 0)) { // The depends-file is older than the dependee. regenerate = true; diff --git a/Source/cmDepends.h b/Source/cmDepends.h index 20c91ca..fc6571d 100644 --- a/Source/cmDepends.h +++ b/Source/cmDepends.h @@ -12,7 +12,7 @@ #include <string> #include <vector> -class cmFileTimeComparison; +class cmFileTimeCache; class cmLocalGenerator; /** \class cmDepends @@ -72,10 +72,7 @@ public: void Clear(const std::string& file); /** Set the file comparison object */ - void SetFileComparison(cmFileTimeComparison* fc) - { - this->FileComparison = fc; - } + void SetFileTimeCache(cmFileTimeCache* fc) { this->FileTimeCache = fc; } protected: // Write dependencies for the target file to the given stream. @@ -101,7 +98,7 @@ protected: // Flag for verbose output. bool Verbose = false; - cmFileTimeComparison* FileComparison = nullptr; + cmFileTimeCache* FileTimeCache = nullptr; std::string Language; diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index a85f5ee..58b4ebb 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -6,6 +6,7 @@ #include <utility> #include "cmAlgorithms.h" +#include "cmFileTime.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" @@ -247,6 +248,8 @@ void cmDependsC::ReadCacheFile() cmIncludeLines* cacheEntry = nullptr; bool haveFileName = false; + cmFileTime cacheFileTime; + bool const cacheFileTimeGood = cacheFileTime.Load(this->CacheFileName); while (cmSystemTools::GetLineFromStream(fin, line)) { if (line.empty()) { cacheEntry = nullptr; @@ -256,11 +259,12 @@ void cmDependsC::ReadCacheFile() // the first line after an empty line is the name of the parsed file if (!haveFileName) { haveFileName = true; - int newer = 0; - bool res = - cmSystemTools::FileTimeCompare(this->CacheFileName, line, &newer); - if (res && newer == 1) // cache is newer than the parsed file + cmFileTime fileTime; + bool const res = cacheFileTimeGood && fileTime.Load(line); + bool const newer = res && cacheFileTime.Newer(fileTime); + + if (res && newer) // cache is newer than the parsed file { cacheEntry = new cmIncludeLines; this->FileCache[line] = cacheEntry; diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 560d893..8913e6d 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -532,7 +532,7 @@ bool cmFileCopier::InstallFile(const std::string& fromFile, bool copy = true; if (!this->Always) { // If both files exist with the same time do not copy. - if (!this->FileTimes.FileTimesDiffer(fromFile, toFile)) { + if (!this->FileTimes.DifferS(fromFile, toFile)) { copy = false; } } diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h index a11c371..003b8f6 100644 --- a/Source/cmFileCopier.h +++ b/Source/cmFileCopier.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmFileTimeComparison.h" +#include "cmFileTimeCache.h" #include "cm_sys_stat.h" #include "cmsys/RegularExpression.hxx" @@ -28,7 +28,7 @@ protected: cmMakefile* Makefile; const char* Name; bool Always; - cmFileTimeComparison FileTimes; + cmFileTimeCache FileTimes; // Whether to install a file not matching any expression. bool MatchlessFiles; diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx new file mode 100644 index 0000000..253457f --- /dev/null +++ b/Source/cmFileTime.cxx @@ -0,0 +1,49 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileTime.h" + +#include <string> +#include <time.h> + +// Use a platform-specific API to get file times efficiently. +#if !defined(_WIN32) || defined(__CYGWIN__) +# include "cm_sys_stat.h" +#else +# include "cmsys/Encoding.hxx" +# include <windows.h> +#endif + +bool cmFileTime::Load(std::string const& fileName) +{ +#if !defined(_WIN32) || defined(__CYGWIN__) + // POSIX version. Use the stat function. + struct stat fst; + if (::stat(fileName.c_str(), &fst) != 0) { + return false; + } +# if CMake_STAT_HAS_ST_MTIM + // Nanosecond resolution + this->NS = fst.st_mtim.tv_sec * NsPerS + fst.st_mtim.tv_nsec; +# elif CMake_STAT_HAS_ST_MTIMESPEC + // Nanosecond resolution + this->NS = fst.st_mtimespec.tv_sec * NsPerS + fst.st_mtimespec.tv_nsec; +# else + // Second resolution + this->NS = fst.st_mtime * NsPerS; +# endif +#else + // Windows version. Get the modification time from extended file attributes. + WIN32_FILE_ATTRIBUTE_DATA fdata; + if (!GetFileAttributesExW(cmsys::Encoding::ToWide(fileName).c_str(), + GetFileExInfoStandard, &fdata)) { + return false; + } + + // Copy the file time to the output location. + this->NS = (static_cast<NSC>(fdata.ftLastWriteTime.dwHighDateTime) << 32) | + static_cast<NSC>(fdata.ftLastWriteTime.dwLowDateTime); + // The file time resolution is 100 ns. + this->NS *= 100; +#endif + return true; +} diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h new file mode 100644 index 0000000..4c8e556 --- /dev/null +++ b/Source/cmFileTime.h @@ -0,0 +1,130 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmFileTime_h +#define cmFileTime_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> + +/** \class cmFileTime + * \brief Abstract file modification time with support for comparison with + * other file modification times. + */ +class cmFileTime +{ +public: + typedef long long NSC; + static constexpr NSC NsPerS = 1000000000; + + cmFileTime() = default; + ~cmFileTime() = default; + + /** + * @brief Loads the file time of fileName from the file system + * @return true on success + */ + bool Load(std::string const& fileName); + + /** + * @brief Return true if this is older than ftm + */ + bool Older(cmFileTime const& ftm) const { return (this->NS - ftm.NS) < 0; } + + /** + * @brief Return true if this is newer than ftm + */ + bool Newer(cmFileTime const& ftm) const { return (ftm.NS - this->NS) < 0; } + + /** + * @brief Return true if this is the same as ftm + */ + bool Equal(cmFileTime const& ftm) const { return this->NS == ftm.NS; } + + /** + * @brief Return true if this is not the same as ftm + */ + bool Differ(cmFileTime const& ftm) const { return this->NS != ftm.NS; } + + /** + * @brief Compare file modification times. + * @return -1, 0, +1 for this older, same, or newer than ftm. + */ + int Compare(cmFileTime const& ftm) + { + NSC const diff = this->NS - ftm.NS; + if (diff == 0) { + return 0; + } + return (diff < 0) ? -1 : 1; + } + + // -- Comparison in second resolution + + /** + * @brief Return true if this is at least a second older than ftm + */ + bool OlderS(cmFileTime const& ftm) const + { + return (ftm.NS - this->NS) >= cmFileTime::NsPerS; + } + + /** + * @brief Return true if this is at least a second newer than ftm + */ + bool NewerS(cmFileTime const& ftm) const + { + return (this->NS - ftm.NS) >= cmFileTime::NsPerS; + } + + /** + * @brief Return true if this is within the same second as ftm + */ + bool EqualS(cmFileTime const& ftm) const + { + NSC diff = this->NS - ftm.NS; + if (diff < 0) { + diff = -diff; + } + return (diff < cmFileTime::NsPerS); + } + + /** + * @brief Return true if this is older or newer than ftm by at least a second + */ + bool DifferS(cmFileTime const& ftm) const + { + NSC diff = this->NS - ftm.NS; + if (diff < 0) { + diff = -diff; + } + return (diff >= cmFileTime::NsPerS); + } + + /** + * @brief Compare file modification times. + * @return -1: this at least a second older, 0: this within the same second + * as ftm, +1: this at least a second newer than ftm. + */ + int CompareS(cmFileTime const& ftm) const + { + NSC const diff = this->NS - ftm.NS; + if (diff <= -cmFileTime::NsPerS) { + return -1; + } + if (diff >= cmFileTime::NsPerS) { + return 1; + } + return 0; + } + + /** + * @brief The file modification time in nanoseconds + */ + NSC GetNS() const { return this->NS; } + +private: + NSC NS = 0; +}; + +#endif diff --git a/Source/cmFileTimeCache.cxx b/Source/cmFileTimeCache.cxx new file mode 100644 index 0000000..1fff6a9 --- /dev/null +++ b/Source/cmFileTimeCache.cxx @@ -0,0 +1,57 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileTimeCache.h" + +#include <string> +#include <unordered_map> +#include <utility> + +cmFileTimeCache::cmFileTimeCache() = default; + +cmFileTimeCache::~cmFileTimeCache() = default; + +bool cmFileTimeCache::Load(std::string const& fileName, cmFileTime& fileTime) +{ + // Use the stored time if available. + { + auto fit = this->FileTimes.find(fileName); + if (fit != this->FileTimes.end()) { + fileTime = fit->second; + return true; + } + } + // Read file time from OS + if (!fileTime.Load(fileName)) { + return false; + } + // Store file time in cache + this->FileTimes[fileName] = fileTime; + return true; +} + +bool cmFileTimeCache::Compare(std::string const& f1, std::string const& f2, + int* result) +{ + // Get the modification time for each file. + cmFileTime ft1, ft2; + if (this->Load(f1, ft1) && this->Load(f2, ft2)) { + // Compare the two modification times. + *result = ft1.Compare(ft2); + return true; + } + // No comparison available. Default to the same time. + *result = 0; + return false; +} + +bool cmFileTimeCache::DifferS(std::string const& f1, std::string const& f2) +{ + // Get the modification time for each file. + cmFileTime ft1, ft2; + if (this->Load(f1, ft1) && this->Load(f2, ft2)) { + // Compare the two modification times. + return ft1.DifferS(ft2); + } + // No comparison available. Default to different times. + return true; +} diff --git a/Source/cmFileTimeCache.h b/Source/cmFileTimeCache.h new file mode 100644 index 0000000..a47904c --- /dev/null +++ b/Source/cmFileTimeCache.h @@ -0,0 +1,51 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmFileTimeCache_h +#define cmFileTimeCache_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cmFileTime.h" +#include <string> +#include <unordered_map> + +/** \class cmFileTimeCache + * \brief Caches file modification times in an internal map for fast lookups. + */ +class cmFileTimeCache +{ +public: + cmFileTimeCache(); + ~cmFileTimeCache(); + + cmFileTimeCache(const cmFileTimeCache&) = delete; + cmFileTimeCache& operator=(const cmFileTimeCache&) = delete; + + /** + * @brief Loads the file time from the cache or the file system. + * @return true on success + */ + bool Load(std::string const& fileName, cmFileTime& fileTime); + + /** + * @brief Compare file modification times. + * @return true for successful comparison and false for error. + * + * When true is returned, result has -1, 0, +1 for + * f1 older, same, or newer than f2. + */ + bool Compare(std::string const& f1, std::string const& f2, int* result); + + /** + * @brief Compare file modification times. + * @return true unless both files exist and have modification times less + * than 1 second apart. + */ + bool DifferS(std::string const& f1, std::string const& f2); + +private: + typedef std::unordered_map<std::string, cmFileTime> FileTimeMap; + FileTimeMap FileTimes; +}; + +#endif diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx deleted file mode 100644 index 8b3911e..0000000 --- a/Source/cmFileTimeComparison.cxx +++ /dev/null @@ -1,233 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmFileTimeComparison.h" - -#include <string> -#include <time.h> -#include <unordered_map> -#include <utility> - -// Use a platform-specific API to get file times efficiently. -#if !defined(_WIN32) || defined(__CYGWIN__) -# include "cm_sys_stat.h" -# define cmFileTimeComparison_Type struct stat -#else -# include "cmsys/Encoding.hxx" -# include <windows.h> -# define cmFileTimeComparison_Type FILETIME -#endif - -class cmFileTimeComparisonInternal -{ -public: - // Internal comparison method. - inline bool FileTimeCompare(const std::string& f1, const std::string& f2, - int* result); - - bool FileTimesDiffer(const std::string& f1, const std::string& f2); - -private: - typedef std::unordered_map<std::string, cmFileTimeComparison_Type> - FileStatsMap; - FileStatsMap Files; - - // Internal methods to lookup and compare modification times. - inline bool Stat(const std::string& fname, cmFileTimeComparison_Type* st); - inline int Compare(cmFileTimeComparison_Type* st1, - cmFileTimeComparison_Type* st2); - inline bool TimesDiffer(cmFileTimeComparison_Type* st1, - cmFileTimeComparison_Type* st2); -}; - -bool cmFileTimeComparisonInternal::Stat(const std::string& fname, - cmFileTimeComparison_Type* st) -{ - // Use the stored time if available. - cmFileTimeComparisonInternal::FileStatsMap::iterator fit = - this->Files.find(fname); - if (fit != this->Files.end()) { - *st = fit->second; - return true; - } - -#if !defined(_WIN32) || defined(__CYGWIN__) - // POSIX version. Use the stat function. - int res = ::stat(fname.c_str(), st); - if (res != 0) { - return false; - } -#else - // Windows version. Get the modification time from extended file - // attributes. - WIN32_FILE_ATTRIBUTE_DATA fdata; - if (!GetFileAttributesExW(cmsys::Encoding::ToWide(fname).c_str(), - GetFileExInfoStandard, &fdata)) { - return false; - } - - // Copy the file time to the output location. - *st = fdata.ftLastWriteTime; -#endif - - // Store the time for future use. - this->Files[fname] = *st; - return true; -} - -cmFileTimeComparison::cmFileTimeComparison() -{ - this->Internals = new cmFileTimeComparisonInternal; -} - -cmFileTimeComparison::~cmFileTimeComparison() -{ - delete this->Internals; -} - -bool cmFileTimeComparison::FileTimeCompare(const std::string& f1, - const std::string& f2, int* result) -{ - return this->Internals->FileTimeCompare(f1, f2, result); -} - -bool cmFileTimeComparison::FileTimesDiffer(const std::string& f1, - const std::string& f2) -{ - return this->Internals->FileTimesDiffer(f1, f2); -} - -int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1, - cmFileTimeComparison_Type* s2) -{ -#if !defined(_WIN32) || defined(__CYGWIN__) -# if CMake_STAT_HAS_ST_MTIM - // Compare using nanosecond resolution. - if (s1->st_mtim.tv_sec < s2->st_mtim.tv_sec) { - return -1; - } - if (s1->st_mtim.tv_sec > s2->st_mtim.tv_sec) { - return 1; - } - if (s1->st_mtim.tv_nsec < s2->st_mtim.tv_nsec) { - return -1; - } - if (s1->st_mtim.tv_nsec > s2->st_mtim.tv_nsec) { - return 1; - } -# elif CMake_STAT_HAS_ST_MTIMESPEC - // Compare using nanosecond resolution. - if (s1->st_mtimespec.tv_sec < s2->st_mtimespec.tv_sec) { - return -1; - } - if (s1->st_mtimespec.tv_sec > s2->st_mtimespec.tv_sec) { - return 1; - } - if (s1->st_mtimespec.tv_nsec < s2->st_mtimespec.tv_nsec) { - return -1; - } - if (s1->st_mtimespec.tv_nsec > s2->st_mtimespec.tv_nsec) { - return 1; - } -# else - // Compare using 1 second resolution. - if (s1->st_mtime < s2->st_mtime) { - return -1; - } - if (s1->st_mtime > s2->st_mtime) { - return 1; - } -# endif - // Files have the same time. - return 0; -#else - // Compare using system-provided function. - return (int)CompareFileTime(s1, s2); -#endif -} - -bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1, - cmFileTimeComparison_Type* s2) -{ -#if !defined(_WIN32) || defined(__CYGWIN__) -# if CMake_STAT_HAS_ST_MTIM - // Times are integers in units of 1ns. - long long bil = 1000000000; - long long t1 = s1->st_mtim.tv_sec * bil + s1->st_mtim.tv_nsec; - long long t2 = s2->st_mtim.tv_sec * bil + s2->st_mtim.tv_nsec; - if (t1 < t2) { - return (t2 - t1) >= bil; - } - if (t2 < t1) { - return (t1 - t2) >= bil; - } - return false; -# elif CMake_STAT_HAS_ST_MTIMESPEC - // Times are integers in units of 1ns. - long long bil = 1000000000; - long long t1 = s1->st_mtimespec.tv_sec * bil + s1->st_mtimespec.tv_nsec; - long long t2 = s2->st_mtimespec.tv_sec * bil + s2->st_mtimespec.tv_nsec; - if (t1 < t2) { - return (t2 - t1) >= bil; - } - if (t2 < t1) { - return (t1 - t2) >= bil; - } - return false; -# else - // Times are integers in units of 1s. - if (s1->st_mtime < s2->st_mtime) { - return (s2->st_mtime - s1->st_mtime) >= 1; - } - if (s1->st_mtime > s2->st_mtime) { - return (s1->st_mtime - s2->st_mtime) >= 1; - } - return false; -# endif -#else - // Times are integers in units of 100ns. - LARGE_INTEGER t1; - LARGE_INTEGER t2; - t1.LowPart = s1->dwLowDateTime; - t1.HighPart = s1->dwHighDateTime; - t2.LowPart = s2->dwLowDateTime; - t2.HighPart = s2->dwHighDateTime; - if (t1.QuadPart < t2.QuadPart) { - return (t2.QuadPart - t1.QuadPart) >= static_cast<LONGLONG>(10000000); - } else if (t2.QuadPart < t1.QuadPart) { - return (t1.QuadPart - t2.QuadPart) >= static_cast<LONGLONG>(10000000); - } else { - return false; - } -#endif -} - -bool cmFileTimeComparisonInternal::FileTimeCompare(const std::string& f1, - const std::string& f2, - int* result) -{ - // Get the modification time for each file. - cmFileTimeComparison_Type s1; - cmFileTimeComparison_Type s2; - if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) { - // Compare the two modification times. - *result = this->Compare(&s1, &s2); - return true; - } - // No comparison available. Default to the same time. - *result = 0; - return false; -} - -bool cmFileTimeComparisonInternal::FileTimesDiffer(const std::string& f1, - const std::string& f2) -{ - // Get the modification time for each file. - cmFileTimeComparison_Type s1; - cmFileTimeComparison_Type s2; - if (this->Stat(f1, &s1) && this->Stat(f2, &s2)) { - // Compare the two modification times. - return this->TimesDiffer(&s1, &s2); - } - // No comparison available. Default to different times. - return true; -} diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h deleted file mode 100644 index b4e4eb3..0000000 --- a/Source/cmFileTimeComparison.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmFileTimeComparison_h -#define cmFileTimeComparison_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <string> - -class cmFileTimeComparisonInternal; - -/** \class cmFileTimeComparison - * \brief Helper class for comparing file modification times. - * - * Compare file modification times or test if file modification times differ. - */ -class cmFileTimeComparison -{ -public: - cmFileTimeComparison(); - ~cmFileTimeComparison(); - - cmFileTimeComparison(const cmFileTimeComparison&) = delete; - cmFileTimeComparison& operator=(const cmFileTimeComparison&) = delete; - - /** - * Compare file modification times. - * Return true for successful comparison and false for error. - * When true is returned, result has -1, 0, +1 for - * f1 older, same, or newer than f2. - */ - bool FileTimeCompare(const std::string& f1, const std::string& f2, - int* result); - - /** - * Compare file modification times. Return true unless both files - * exist and have modification times less than 1 second apart. - */ - bool FileTimesDiffer(const std::string& f1, const std::string& f2); - -protected: - cmFileTimeComparisonInternal* Internals; -}; - -#endif diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index d1093be..f3d5a94 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -12,7 +12,7 @@ #include "cmAlgorithms.h" #include "cmCustomCommandGenerator.h" -#include "cmFileTimeComparison.h" +#include "cmFileTimeCache.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -1273,12 +1273,11 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( // happen when a new source file is added and CMake regenerates the // project but no other sources were touched. bool needRescanDependInfo = false; - cmFileTimeComparison* ftc = - this->GlobalGenerator->GetCMakeInstance()->GetFileComparison(); + cmFileTimeCache* ftc = + this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache(); { int result; - if (!ftc->FileTimeCompare(internalDependFile, tgtInfo, &result) || - result < 0) { + if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) { if (verbose) { std::ostringstream msg; msg << "Dependee \"" << tgtInfo << "\" is newer than depender \"" @@ -1297,7 +1296,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( dirInfoFile += "/CMakeFiles"; dirInfoFile += "/CMakeDirectoryInformation.cmake"; int result; - if (!ftc->FileTimeCompare(internalDependFile, dirInfoFile, &result) || + if (!ftc->Compare(internalDependFile, dirInfoFile, &result) || result < 0) { if (verbose) { std::ostringstream msg; @@ -1318,7 +1317,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( if (!needRescanDirInfo) { cmDependsC checker; checker.SetVerbose(verbose); - checker.SetFileComparison(ftc); + checker.SetFileTimeCache(ftc); // cmDependsC::Check() fills the vector validDependencies() with the // dependencies for those files where they are still valid, i.e. neither // the files themselves nor any files they depend on have changed. @@ -1439,8 +1438,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( if (scanner) { scanner->SetLocalGenerator(this); - scanner->SetFileComparison( - this->GlobalGenerator->GetCMakeInstance()->GetFileComparison()); + scanner->SetFileTimeCache( + this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache()); scanner->SetLanguage(lang); scanner->SetTargetDirectory(targetDir); scanner->Write(ruleFileStream, internalRuleFileStream); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 08e284e..e1b775e 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -9,7 +9,7 @@ #include "cmDocumentationFormatter.h" #include "cmDuration.h" #include "cmExternalMakefileProjectGenerator.h" -#include "cmFileTimeComparison.h" +#include "cmFileTimeCache.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmGlobalGeneratorFactory.h" @@ -138,7 +138,7 @@ cmake::cmake(Role role, cmState::Mode mode) this->DebugOutput = false; this->DebugTryCompile = false; this->ClearBuildSystem = false; - this->FileComparison = new cmFileTimeComparison; + this->FileTimeCache = new cmFileTimeCache; this->State = new cmState; this->State->SetMode(mode); @@ -222,7 +222,7 @@ cmake::~cmake() #ifdef CMAKE_BUILD_WITH_CMAKE delete this->VariableWatch; #endif - delete this->FileComparison; + delete this->FileTimeCache; } #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -2139,7 +2139,7 @@ int cmake::CheckBuildSystem() std::string dep_newest = *dep++; for (; dep != depends.end(); ++dep) { int result = 0; - if (this->FileComparison->FileTimeCompare(dep_newest, *dep, &result)) { + if (this->FileTimeCache->Compare(dep_newest, *dep, &result)) { if (result < 0) { dep_newest = *dep; } @@ -2158,7 +2158,7 @@ int cmake::CheckBuildSystem() std::string out_oldest = *out++; for (; out != outputs.end(); ++out) { int result = 0; - if (this->FileComparison->FileTimeCompare(out_oldest, *out, &result)) { + if (this->FileTimeCache->Compare(out_oldest, *out, &result)) { if (result > 0) { out_oldest = *out; } @@ -2175,8 +2175,7 @@ int cmake::CheckBuildSystem() // If any output is older than any dependency then rerun. { int result = 0; - if (!this->FileComparison->FileTimeCompare(out_oldest, dep_newest, - &result) || + if (!this->FileTimeCache->Compare(out_oldest, dep_newest, &result) || result < 0) { if (verbose) { std::ostringstream msg; @@ -2431,20 +2430,22 @@ static bool cmakeCheckStampFile(const std::string& stampName) } // Compare the stamp dependencies against the dependency file itself. - cmFileTimeComparison ftc; - std::string dep; - while (cmSystemTools::GetLineFromStream(fin, dep)) { - int result; - if (!dep.empty() && dep[0] != '#' && - (!ftc.FileTimeCompare(stampDepends, dep, &result) || result < 0)) { - // The stamp depends file is older than this dependency. The - // build system is really out of date. - std::cout << "CMake is re-running because " << stampName - << " is out-of-date.\n"; - std::cout << " the file '" << dep << "'\n"; - std::cout << " is newer than '" << stampDepends << "'\n"; - std::cout << " result='" << result << "'\n"; - return false; + { + cmFileTimeCache ftc; + std::string dep; + while (cmSystemTools::GetLineFromStream(fin, dep)) { + int result; + if (!dep.empty() && dep[0] != '#' && + (!ftc.Compare(stampDepends, dep, &result) || result < 0)) { + // The stamp depends file is older than this dependency. The + // build system is really out of date. + std::cout << "CMake is re-running because " << stampName + << " is out-of-date.\n"; + std::cout << " the file '" << dep << "'\n"; + std::cout << " is newer than '" << stampDepends << "'\n"; + std::cout << " result='" << result << "'\n"; + return false; + } } } diff --git a/Source/cmake.h b/Source/cmake.h index 1ffeabc..f8a2319 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -26,7 +26,7 @@ class cmExternalMakefileProjectGeneratorFactory; class cmFileAPI; -class cmFileTimeComparison; +class cmFileTimeCache; class cmGlobalGenerator; class cmGlobalGeneratorFactory; class cmMakefile; @@ -329,7 +329,7 @@ public: /** * Get the file comparison class */ - cmFileTimeComparison* GetFileComparison() { return this->FileComparison; } + cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache; } // Do we want debug output during the cmake run. bool GetDebugOutput() { return this->DebugOutput; } @@ -509,7 +509,7 @@ private: std::unordered_set<std::string> HeaderFileExtensionsSet; bool ClearBuildSystem; bool DebugTryCompile; - cmFileTimeComparison* FileComparison; + cmFileTimeCache* FileTimeCache; std::string GraphVizFile; InstalledFilesMap InstalledFiles; |