diff options
author | Alexey Edelev <alexey.edelev@qt.io> | 2021-11-24 16:22:18 +0100 |
---|---|---|
committer | Alexey Edelev <alexey.edelev@qt.io> | 2021-12-02 16:34:23 +0100 |
commit | 63b8840380e70c1258f56c67a2ec5edb5bdea53d (patch) | |
tree | 465fedceda0553c0beec5e5e0f46cd03d1d97abf /src/tools/cmake_automoc_parser | |
parent | 7a6dd6084cb6dc3d8ad0476d9630ad7c575bca19 (diff) |
Fix dependency chain that collects the metatype json files
cmake_automoc_parser has the logic preventing the run of moc with the
--collect-json parameter if metatype json files are not changed.
This logic only verify if the file list is changed but not their
content. This change adds a timestamp file that contains the last
metatype json file timestamp that was modified during the last
cmake_automoc_parser run. The logic still prevents of running
'moc --collect-json' when the list of metatype json files is not
changed, but also checks if their content is no changed.
Another approach it to generate the depfile that can be utilized by
CMake in add_custom_command as DEPFILE argument. But this concept only
works from the second build attempt because of an issue related to
dyndep.
Pick-to: 6.2
Fixes: QTBUG-98532
Change-Id: I713f8bfa9ae769cefe0beac0b7fa19750b00a765
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src/tools/cmake_automoc_parser')
-rw-r--r-- | src/tools/cmake_automoc_parser/main.cpp | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/src/tools/cmake_automoc_parser/main.cpp b/src/tools/cmake_automoc_parser/main.cpp index 6d0214638e..70cfcb1b68 100644 --- a/src/tools/cmake_automoc_parser/main.cpp +++ b/src/tools/cmake_automoc_parser/main.cpp @@ -30,6 +30,7 @@ #include <cstdio> #include <cstdlib> +#include <limits> #include <qcommandlineoption.h> #include <qcommandlineparser.h> @@ -46,6 +47,7 @@ #include <qset.h> #include <qstring.h> #include <qstack.h> +#include <qdatastream.h> QT_BEGIN_NAMESPACE @@ -194,38 +196,52 @@ static bool readParseCache(ParseCacheMap &entries, const QString &parseCacheFile return true; } -static bool readJsonFiles(QList<QString> &entries, const QString &filePath) +static bool writeJsonFiles(const QList<QString> &fileList, const QString &fileListFilePath, + const QString ×tampFilePath) { - - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - fprintf(stderr, "Could not open: %s\n", qPrintable(filePath)); + QFile timestampFile(timestampFilePath); + if (!timestampFile.open(QIODevice::ReadWrite)) { + fprintf(stderr, "Could not open: %s\n", qPrintable(timestampFilePath)); return false; } - QTextStream textStream(&file); - QString line; - while (textStream.readLineInto(&line)) { - entries.push_back(line); + qint64 timestamp = std::numeric_limits<qint64>::min(); + QByteArray timestampBuffer = timestampFile.readAll(); + if (timestampBuffer.size() == sizeof(timestamp)) { + QDataStream istream(×tampBuffer, QIODevice::ReadOnly); + istream >> timestamp; } - file.close(); - return true; -} -static bool writeJsonFiles(const QList<QString> &fileList, const QString &fileListFilePath) -{ - QFile file(fileListFilePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - fprintf(stderr, "Could not open: %s\n", qPrintable(fileListFilePath)); - return false; + // Check if any of the metatype json files produced by automoc is newer than the last file + // processed by cmake_automoc parser + for (const auto &jsonFile : fileList) { + const qint64 jsonFileLastModified = + QFileInfo(jsonFile).lastModified().toMSecsSinceEpoch(); + if (jsonFileLastModified > timestamp) { + timestamp = jsonFileLastModified; + } } - QTextStream textStream(&file); - for (const auto &file : fileList) { - textStream << file << Qt::endl; - } + if (timestamp != std::numeric_limits<qint64>::min() || !QFile::exists(fileListFilePath)) { + QFile file(fileListFilePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + fprintf(stderr, "Could not open: %s\n", qPrintable(fileListFilePath)); + return false; + } - file.close(); + QTextStream textStream(&file); + for (const auto &jsonFile : fileList) { + textStream << jsonFile << Qt::endl; + } + textStream.flush(); + + // Update the timestamp according the newest json file timestamp. + timestampBuffer.clear(); + QDataStream ostream(×tampBuffer, QIODevice::WriteOnly); + ostream << timestamp; + timestampFile.resize(0); + timestampFile.write(timestampBuffer); + } return true; } @@ -270,6 +286,13 @@ int main(int argc, char **argv) QStringLiteral("Set this option when using CMake with a multi-config generator")); parser.addOption(isMultiConfigOption); + QCommandLineOption timestampFilePathOption(QStringLiteral("timestamp-file-path")); + timestampFilePathOption.setDescription( + QStringLiteral("The path to a timestamp file that determines whether the output" + " file needs to be updated.")); + timestampFilePathOption.setValueName(QStringLiteral("timestamp file")); + parser.addOption(timestampFilePathOption); + QStringList arguments = QCoreApplication::arguments(); parser.process(arguments); @@ -378,19 +401,9 @@ int main(int argc, char **argv) jsonFileList.sort(); // Read Previous file list (if any) - const QString fileListFilePath = parser.value(outputFileOption); - QList<QString> previousList; - QFile prev_file(fileListFilePath); - - // Only try to open file if it exists to avoid error messages - if (prev_file.exists()) { - (void)readJsonFiles(previousList, fileListFilePath); - } - - if (previousList != jsonFileList || !QFile(fileListFilePath).exists()) { - if (!writeJsonFiles(jsonFileList, fileListFilePath)) { - return EXIT_FAILURE; - } + if (!writeJsonFiles(jsonFileList, parser.value(outputFileOption), + parser.value(timestampFilePathOption))) { + return EXIT_FAILURE; } return EXIT_SUCCESS; |