summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst3
-rw-r--r--Source/cmQtAutoGenInitializer.cxx1
-rw-r--r--Source/cmQtAutoMocUic.cxx92
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Qt5.cmake8
10 files changed, 97 insertions, 21 deletions
diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
index 69957bf..6eda26c 100644
--- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
@@ -26,6 +26,9 @@ See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference.
By default :prop_tgt:`AUTOMOC_DEPEND_FILTERS` is initialized from
:variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default.
+From Qt 5.15.0 on this variable is ignored as moc is able to output the correct
+dependencies.
+
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index ebb522b..d9b0aff 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1409,6 +1409,7 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
+ info.SetUInt("QT_VERSION_MINOR", this->QtVersion.Minor);
info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable);
info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable);
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index fa5129d..82464a7 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -25,6 +25,8 @@
#include "cmCryptoHash.h"
#include "cmFileTime.h"
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
@@ -170,7 +172,7 @@ public:
// -- Attributes
// - Config
bool MultiConfig = false;
- unsigned int QtVersionMajor = 4;
+ IntegerVersion QtVersion = { 4, 0 };
unsigned int ThreadCount = 0;
// - Directories
std::string AutogenBuildDir;
@@ -216,6 +218,7 @@ public:
bool SettingsChanged = false;
bool RelaxedMode = false;
bool PathPrefix = false;
+ bool CanOutputDependencies = false;
cmFileTime ExecutableTime;
std::string Executable;
std::string CompFileAbs;
@@ -485,8 +488,17 @@ public:
class JobCompileMocT : public JobCompileT
{
public:
- using JobCompileT::JobCompileT;
+ JobCompileMocT(MappingHandleT uicMapping,
+ std::unique_ptr<std::string> reason,
+ ParseCacheT::FileHandleT cacheEntry)
+ : JobCompileT(std::move(uicMapping), std::move(reason))
+ , CacheEntry(std::move(cacheEntry))
+ {
+ }
void Process() override;
+
+ protected:
+ ParseCacheT::FileHandleT CacheEntry;
};
/** uic compiles a file. */
@@ -546,6 +558,9 @@ private:
void Abort(bool error);
// -- Generation
bool CreateDirectories();
+ // -- Support for depfiles
+ static std::vector<std::string> dependenciesFromDepFile(
+ const char* filePath);
private:
// -- Settings
@@ -951,7 +966,7 @@ void cmQtAutoMocUicT::JobParseT::MocMacro()
void cmQtAutoMocUicT::JobParseT::MocDependecies()
{
- if (MocConst().DependFilters.empty()) {
+ if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) {
return;
}
@@ -1674,8 +1689,13 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping,
if (Probe(*mapping, reason.get())) {
// Register the parent directory for creation
MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
+ // Fetch the cache entry for the source file
+ std::string const& sourceFile = mapping->SourceFile->FileName;
+ ParseCacheT::GetOrInsertT cacheEntry =
+ BaseEval().ParseCache.GetOrInsert(sourceFile);
// Add moc job
- Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason));
+ Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(
+ mapping, std::move(reason), std::move(cacheEntry.first));
// Check if a moc job for a mocs_compilation.cpp entry was generated
if (compFile) {
MocEval().CompUpdated = true;
@@ -1779,6 +1799,14 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
std::string const& sourceDir, std::string const& includeString) const
{
using ResPair = std::pair<std::string, cmFileTime>;
+ // moc's dependency file contains absolute paths
+ if (MocConst().CanOutputDependencies) {
+ ResPair res{ includeString, {} };
+ if (res.second.Load(res.first)) {
+ return res;
+ }
+ return {};
+ }
// Search in vicinity of the source
{
ResPair res{ sourceDir + includeString, {} };
@@ -1947,6 +1975,9 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
}
// Add extra options
cm::append(cmd, MocConst().OptionsExtra);
+ if (MocConst().CanOutputDependencies) {
+ cmd.emplace_back("--output-dep-file");
+ }
// Add output file
cmd.emplace_back("-o");
cmd.push_back(outputFile);
@@ -1956,12 +1987,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
// Execute moc command
cmWorkerPool::ProcessResultT result;
- if (RunProcess(GenT::MOC, result, cmd, Reason.get())) {
- // Moc command success. Print moc output.
- if (!result.StdOut.empty()) {
- Log().Info(GenT::MOC, result.StdOut);
- }
- } else {
+ if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) {
// Moc command failed
std::string includers;
if (!Mapping->IncluderFiles.empty()) {
@@ -1976,6 +2002,28 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
MessagePath(outputFile), '\n', includers,
result.ErrorMessage),
cmd, result.StdOut);
+ return;
+ }
+
+ // Moc command success. Print moc output.
+ if (!result.StdOut.empty()) {
+ Log().Info(GenT::MOC, result.StdOut);
+ }
+
+ // Extract dependencies from the dep file moc generated for us
+ if (MocConst().CanOutputDependencies) {
+ const std::string depfile = outputFile + ".d";
+ if (Log().Verbose()) {
+ Log().Info(GenT::MOC,
+ "Reading dependencies from " + MessagePath(depfile));
+ }
+ if (!cmSystemTools::FileExists(depfile)) {
+ Log().Warning(GenT::MOC,
+ "Dependency file " + MessagePath(depfile) +
+ " does not exist.");
+ return;
+ }
+ CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str());
}
}
@@ -1992,7 +2040,7 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
auto optionIt = UicConst().UiFiles.find(sourceFile);
if (optionIt != UicConst().UiFiles.end()) {
UicMergeOptions(allOpts, optionIt->second.Options,
- (BaseConst().QtVersionMajor == 5));
+ (BaseConst().QtVersion.Major == 5));
}
cm::append(cmd, allOpts);
}
@@ -2082,7 +2130,8 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
{
// -- Required settings
if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
- !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) ||
+ !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) ||
+ !info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) ||
!info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
!info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
!info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir,
@@ -2143,8 +2192,10 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
MocConst_.MacroFilters.emplace_back(
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
}
- // Dependency filters
- {
+ // Can moc output dependencies or do we need to setup dependency filters?
+ if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) {
+ MocConst_.CanOutputDependencies = true;
+ } else {
Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS");
if (!val.isArray()) {
return info.LogError("MOC_DEPEND_FILTERS JSON value is not an array.");
@@ -2660,6 +2711,19 @@ bool cmQtAutoMocUicT::CreateDirectories()
return true;
}
+std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
+ const char* filePath)
+{
+ cmGccDepfileContent content = cmReadGccDepfile(filePath);
+ if (content.empty()) {
+ return {};
+ }
+
+ // Moc outputs a depfile with exactly one rule.
+ // Discard the rule and return the dependencies.
+ return content.front().paths;
+}
+
void cmQtAutoMocUicT::Abort(bool error)
{
if (error) {
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp
index e1fdf0b..198ae98 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp
@@ -10,7 +10,7 @@ class StyleA : public QStylePlugin
Q_OBJECT
// Json file in source local directory
Q_PLUGIN_METADATA(IID "org.styles.A" FILE "StyleA.json")
- A_CUSTOM_MACRO(SomeArg, "StyleA_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.A, "StyleA_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp
index 7550d0c..8ce8d77 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp
@@ -10,7 +10,7 @@ class StyleB : public QStylePlugin
Q_OBJECT
// Json file in source local subdirectory
Q_PLUGIN_METADATA(IID "org.styles.B" FILE "jsonIn/StyleB.json")
- A_CUSTOM_MACRO(SomeArg, "jsonIn/StyleB_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.B, "jsonIn/StyleB_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp
index ec71bec..53171e3 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp
@@ -10,7 +10,7 @@ class StyleC : public QStylePlugin
Q_OBJECT
// Json file in global root directory
Q_PLUGIN_METADATA(IID "org.styles.C" FILE "StyleC.json")
- A_CUSTOM_MACRO(SomeArg, "StyleC_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.C, "StyleC_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp
index 3c093b9..29674f9 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp
@@ -10,7 +10,7 @@ class StyleD : public QStylePlugin
Q_OBJECT
// Json file in global sub director
Q_PLUGIN_METADATA(IID "org.styles.D" FILE "sub/StyleD.json")
- A_CUSTOM_MACRO(SomeArg, "sub/StyleD_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.D, "sub/StyleD_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp
index 5f10fb4..7318220 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp
@@ -10,7 +10,7 @@ class StyleE : public QStylePlugin
Q_OBJECT
// Json files in global root directory
Q_PLUGIN_METADATA(IID "org.styles.E" FILE "StyleE.json")
- A_CUSTOM_MACRO(SomeArg, "StyleE_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.E, "StyleE_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp
index 53a4284..2f558a8 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp
@@ -1,7 +1,7 @@
#ifndef UTILITYMACROS_HPP
#define UTILITYMACROS_HPP
-// Empty test macro definition
-#define A_CUSTOM_MACRO(name, jsonFile, pluginRegistrations)
+#define A_CUSTOM_MACRO(url, jsonFile, pluginRegistrations) \
+ Q_PLUGIN_METADATA(IID #url FILE jsonFile)
#endif
diff --git a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
index 6a80b1d..dfc0f50 100644
--- a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
@@ -11,8 +11,16 @@ target_link_libraries(exe PRIVATE Qt5::Core)
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
generate_output_files(exe)
+set(moc_writes_depfiles 0)
+if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0")
+ set(moc_writes_depfiles 1)
+endif()
+
set(autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/mocs_compilation.cpp")
foreach(c IN LISTS CMAKE_CONFIGURATION_TYPES)
list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp")
+ if(moc_writes_depfiles)
+ list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp.d")
+ endif()
endforeach()
file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(AUTOGEN_FILES [==[${autogen_files}]==])\n")