From e9a8a207ad6817cc93eab2b878de090b5ece8bfe Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 22 Feb 2017 17:44:35 +0100 Subject: Autogen: Log simplifications --- Source/cmQtAutoGenerators.cxx | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index d51efb4..373a192 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -272,9 +272,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( filename += "/AutogenInfo.cmake"; if (!makefile->ReadListFile(filename.c_str())) { - std::ostringstream err; - err << "AutoGen: error processing file: " << filename << std::endl; - this->LogError(err.str()); + this->LogError("AutoGen: Error processing file: " + filename); return false; } @@ -333,10 +331,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( cmSystemTools::ExpandListArgument( makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS"), uicOptionsVec); if (uicFilesVec.size() != uicOptionsVec.size()) { - std::ostringstream err; - err << "AutoGen: Error: Uic files/options lists size missmatch in: " - << filename << std::endl; - this->LogError(err.str()); + this->LogError( + "AutoGen: Error: Uic files/options lists size missmatch in: " + + filename); return false; } for (std::vector::iterator fileIt = uicFilesVec.begin(), @@ -358,10 +355,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( cmSystemTools::ExpandListArgument( makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS"), rccOptionsVec); if (rccFilesVec.size() != rccOptionsVec.size()) { - std::ostringstream err; - err << "AutoGen: Error: RCC files/options lists size missmatch in: " - << filename << std::endl; - this->LogError(err.str()); + this->LogError( + "AutoGen: Error: RCC files/options lists size missmatch in: " + + filename); return false; } for (std::vector::iterator fileIt = rccFilesVec.begin(), @@ -381,10 +377,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( rccInputLists.resize(this->RccSources.size()); } if (this->RccSources.size() != rccInputLists.size()) { - std::ostringstream err; - err << "AutoGen: Error: RCC sources/inputs lists size missmatch in: " - << filename << std::endl; - this->LogError(err.str()); + this->LogError( + "AutoGen: Error: RCC sources/inputs lists size missmatch in: " + + filename); return false; } for (std::vector::iterator fileIt = this->RccSources.begin(), @@ -480,12 +475,8 @@ bool cmQtAutoGenerators::SettingsFileWrite(const std::string& targetDirectory) success = false; // Remove old settings file to trigger full rebuild on next run cmSystemTools::RemoveFile(filename); - { - std::ostringstream err; - err << "AutoGen: Error: Writing old settings file failed: " - << filename; - this->LogError(err.str()); - } + this->LogError("AutoGen: Error: Writing old settings file failed: " + + filename); } } return success; @@ -1150,13 +1141,13 @@ bool cmQtAutoGenerators::MocGenerateAll( outfile.open(this->MocCppFilenameAbs.c_str(), std::ios::trunc); if (!outfile) { success = false; - this->LogError("AutoMoc: error opening " + this->MocCppFilenameAbs); + this->LogError("AutoMoc: Error opening " + this->MocCppFilenameAbs); } else { outfile << automocSource; // Check for write errors if (!outfile.good()) { success = false; - this->LogError("AutoMoc: error writing " + this->MocCppFilenameAbs); + this->LogError("AutoMoc: Error writing " + this->MocCppFilenameAbs); } } } @@ -1768,7 +1759,7 @@ bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const if (!dirName.empty()) { success = cmsys::SystemTools::MakeDirectory(dirName); if (!success) { - this->LogError("AutoGen: Directory creation failed: " + dirName); + this->LogError("AutoGen: Error: Directory creation failed: " + dirName); } } return success; -- cgit v0.12 From 2a6fd4328adfad4cae0097d6d71e571c122fc0d1 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 22 Feb 2017 17:52:16 +0100 Subject: Autogen: Single point of return in Run() method --- Source/cmQtAutoGenerators.cxx | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 373a192..4463d62 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -244,23 +244,20 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory, CM_AUTO_PTR mf(new cmMakefile(&gg, snapshot)); gg.SetCurrentMakefile(mf.get()); - if (!this->ReadAutogenInfoFile(mf.get(), targetDirectory, config)) { - return false; - } - // Read old settings - this->SettingsFileRead(mf.get(), targetDirectory); - // Init and run - this->Init(mf.get()); - if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - if (!this->RunAutogen()) { - return false; + bool success = false; + if (this->ReadAutogenInfoFile(mf.get(), targetDirectory, config)) { + // Read old settings + this->SettingsFileRead(mf.get(), targetDirectory); + // Init and run + this->Init(mf.get()); + if (this->RunAutogen()) { + // Write current settings + if (this->SettingsFileWrite(targetDirectory)) { + success = true; + } } } - // Write latest settings - if (!this->SettingsFileWrite(targetDirectory)) { - return false; - } - return true; + return success; } bool cmQtAutoGenerators::ReadAutogenInfoFile( @@ -295,6 +292,13 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( this->QtMajorVersion = makefile->GetSafeDefinition("AM_Qt5Core_VERSION_MAJOR"); } + // Check Qt version + if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) { + this->LogError("AutoGen: Error: Unsupported Qt version: \"" + + this->QtMajorVersion + "\""); + return false; + } + this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE"); this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE"); -- cgit v0.12 From 70ebf35cdaaf391138df7564a07cd205de4af971 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 22 Feb 2017 17:40:36 +0100 Subject: Autogen: Add AUTOMOC_DEPEND_FILTERS support --- Modules/AutogenInfo.cmake.in | 1 + Source/cmQtAutoGeneratorInitializer.cxx | 2 ++ Source/cmQtAutoGenerators.cxx | 60 +++++++++++++++++++++++++++------ Source/cmQtAutoGenerators.h | 1 + Source/cmTarget.cxx | 1 + 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index b647ecf..fc5024f 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -20,6 +20,7 @@ set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@) set(AM_MOC_INCLUDES @_moc_incs@) set(AM_MOC_OPTIONS @_moc_options@) set(AM_MOC_RELAXED_MODE @_moc_relaxed_mode@) +set(AM_MOC_DEPEND_FILTERS @_moc_depend_filters@) # UIC settings set(AM_UIC_SKIP @_uic_skip@) set(AM_UIC_TARGET_OPTIONS @_uic_target_options@) diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 52112ff..de18265 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -218,6 +218,8 @@ static void MocSetupAutoTarget( AddDefinitionEscaped(makefile, "_moc_relaxed_mode", makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE") ? "TRUE" : "FALSE"); + AddDefinitionEscaped(makefile, "_moc_depend_filters", + GetSafeProperty(target, "AUTOMOC_DEPEND_FILTERS")); // Moc includes and compile definitions { diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 4463d62..e1b4f35 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -260,6 +260,32 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory, return success; } +bool cmQtAutoGenerators::MocDependFilterPush(const std::string& key, + const std::string& regExp) +{ + bool success = false; + if (!key.empty()) { + if (!regExp.empty()) { + MocDependFilter filter; + filter.key = key; + if (filter.regExp.compile(regExp)) { + this->MocDependFilters.push_back(filter); + success = true; + } else { + this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Compiling " + "regular expression failed.\nKey: \"" + + key + "\"\nReg. exp.: \"" + regExp + "\""); + } + } else { + this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Regular " + "expression is empty"); + } + } else { + this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Key is empty"); + } + return success; +} + bool cmQtAutoGenerators::ReadAutogenInfoFile( cmMakefile* makefile, const std::string& targetDirectory, const std::string& config) @@ -320,6 +346,30 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( this->MocIncludePaths); cmSystemTools::ExpandListArgument( makefile->GetSafeDefinition("AM_MOC_OPTIONS"), this->MocOptions); + { + std::vector mocDependFilters; + cmSystemTools::ExpandListArgument( + makefile->GetSafeDefinition("AM_MOC_DEPEND_FILTERS"), mocDependFilters); + // Insert Q_PLUGIN_METADATA dependency filter + if (this->QtMajorVersion != "4") { + this->MocDependFilterPush("Q_PLUGIN_METADATA", + "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\(" + "[^\\)]*FILE[ \t]*\"([^\"]+)\""); + } + // Insert user defined dependency filters + if ((mocDependFilters.size() % 2) == 0) { + for (std::vector::const_iterator dit = + mocDependFilters.begin(); + dit != mocDependFilters.end(); dit += 2) { + if (!this->MocDependFilterPush(*dit, *(dit + 1))) { + return false; + } + } + } else { + this->LogError("AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not " + "a multiple of 2"); + } + } // - Uic cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_UIC_SKIP"), @@ -559,16 +609,6 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile) this->MocIncludes.push_back(*it); } } - - // Insert MocDependFilter for Q_PLUGIN_METADATA - if (QtMajorVersion != "4") { - MocDependFilter filter; - filter.key = "Q_PLUGIN_METADATA"; - filter.regExp.compile("[\n][ \t]*" - "Q_PLUGIN_METADATA[ \t]*\\(" - "[^\\)]*FILE[ \t]*\"([^\"]+)\""); - this->MocDependFilters.push_back(filter); - } } bool cmQtAutoGenerators::RunAutogen() diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index c20b83c..e4b7f60 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -33,6 +33,7 @@ private: typedef std::pair MacroFilter; // - Configuration + bool MocDependFilterPush(const std::string& key, const std::string& regExp); bool ReadAutogenInfoFile(cmMakefile* makefile, const std::string& targetDirectory, const std::string& config); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ad3d604..0f3d91b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -245,6 +245,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("AUTOMOC", CM_NULLPTR); this->SetPropertyDefault("AUTOUIC", CM_NULLPTR); this->SetPropertyDefault("AUTORCC", CM_NULLPTR); + this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", CM_NULLPTR); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", CM_NULLPTR); this->SetPropertyDefault("AUTOUIC_OPTIONS", CM_NULLPTR); this->SetPropertyDefault("AUTORCC_OPTIONS", CM_NULLPTR); -- cgit v0.12 From 94e3f82cf114d12b190d1999a72838018eb171c9 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 22 Feb 2017 21:08:36 +0100 Subject: Autogen: Add AUTOMOC_DEPEND_FILTERS test --- Tests/QtAutogen/CMakeLists.txt | 22 ++++++++++++++++++---- Tests/QtAutogen/mocPlugin/CMakeLists.txt | 11 +++++++++-- Tests/QtAutogen/mocPlugin/StyleA.hpp | 2 ++ Tests/QtAutogen/mocPlugin/StyleA_Custom.json | 1 + Tests/QtAutogen/mocPlugin/StyleB.hpp | 2 ++ Tests/QtAutogen/mocPlugin/StyleC.hpp | 2 ++ Tests/QtAutogen/mocPlugin/StyleCommon.hpp | 7 +++++++ Tests/QtAutogen/mocPlugin/StyleD.hpp | 2 ++ Tests/QtAutogen/mocPlugin/StyleE.hpp | 2 ++ .../QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json | 1 + 10 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 Tests/QtAutogen/mocPlugin/StyleA_Custom.json create mode 100644 Tests/QtAutogen/mocPlugin/StyleCommon.hpp create mode 100644 Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 260331b..257c187 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -247,10 +247,7 @@ if (NOT QT_TEST_VERSION STREQUAL 4) execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${mocPluginBinDir}/jsonFiles/StyleC.json") execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${mocPluginBinDir}/jsonFiles/sub/StyleD.json") - - execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin" - ) + execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPluginBinDir}") file(TIMESTAMP "${style_a_file}" style_a_after "${timeformat}") file(TIMESTAMP "${style_b_file}" style_b_after "${timeformat}") @@ -269,6 +266,23 @@ if (NOT QT_TEST_VERSION STREQUAL 4) if (NOT style_d_after GREATER style_d_before) message(SEND_ERROR "file (${style_d_file}) should have changed!") endif() + + # Test custom macro + file(TIMESTAMP "${style_c_file}" style_c_before "${timeformat}") + file(TIMESTAMP "${style_d_file}" style_d_before "${timeformat}") + execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) + execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${mocPluginBinDir}/jsonFiles/StyleC_Custom.json") + execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${mocPluginBinDir}/jsonFiles/sub/StyleD_Custom.json") + execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPluginBinDir}") + file(TIMESTAMP "${style_c_file}" style_c_after "${timeformat}") + file(TIMESTAMP "${style_d_file}" style_d_after "${timeformat}") + if (NOT style_c_after GREATER style_c_before) + message(SEND_ERROR "file (${style_c_file}) should have changed!") + endif() + if (NOT style_d_after GREATER style_d_before) + message(SEND_ERROR "file (${style_d_file}) should have changed!") + endif() + endif() # -- Test diff --git a/Tests/QtAutogen/mocPlugin/CMakeLists.txt b/Tests/QtAutogen/mocPlugin/CMakeLists.txt index eed7d39..b72b05d 100644 --- a/Tests/QtAutogen/mocPlugin/CMakeLists.txt +++ b/Tests/QtAutogen/mocPlugin/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required(VERSION 3.8) +set(CMAKE_AUTOMOC_DEPEND_FILTERS + "A_CUSTOM_MACRO" + "[\n][ \t]*A_CUSTOM_MACRO[ \t\r\n]*\\([^,]+,[ \t\r\n]*\"([^\"]+)\"" + ) + if (NOT QT_TEST_VERSION STREQUAL 5) message(SEND_ERROR "Invalid Qt version specified.") endif() @@ -9,8 +14,10 @@ if(Qt5_POSITION_INDEPENDENT_CODE AND CMAKE_CXX_COMPILE_OPTIONS_PIC) add_definitions(${CMAKE_CXX_COMPILE_OPTIONS_PIC}) endif() -configure_file(jsonIn/StyleC.json jsonFiles/StyleC.json @ONLY) -configure_file(jsonIn/StyleD.json jsonFiles/sub/StyleD.json @ONLY) +configure_file(jsonIn/StyleC.json jsonFiles/StyleC.json) +configure_file(jsonIn/StyleD.json jsonFiles/sub/StyleD.json) +configure_file(jsonIn/StyleC.json jsonFiles/StyleC_Custom.json) +configure_file(jsonIn/StyleD.json jsonFiles/sub/StyleD_Custom.json) # Enable automoc set(CMAKE_AUTOMOC TRUE) diff --git a/Tests/QtAutogen/mocPlugin/StyleA.hpp b/Tests/QtAutogen/mocPlugin/StyleA.hpp index b105b02..1b6154d 100644 --- a/Tests/QtAutogen/mocPlugin/StyleA.hpp +++ b/Tests/QtAutogen/mocPlugin/StyleA.hpp @@ -1,6 +1,7 @@ #ifndef STYLEA_HPP #define STYLEA_HPP +#include "StyleCommon.hpp" #include class StyleA : public QStylePlugin @@ -8,6 +9,7 @@ class StyleA : public QStylePlugin Q_OBJECT // Json file in local directory Q_PLUGIN_METADATA(IID "org.styles.A" FILE "StyleA.json") + A_CUSTOM_MACRO(SomeArg, "StyleA_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/mocPlugin/StyleA_Custom.json b/Tests/QtAutogen/mocPlugin/StyleA_Custom.json new file mode 100644 index 0000000..cc33953 --- /dev/null +++ b/Tests/QtAutogen/mocPlugin/StyleA_Custom.json @@ -0,0 +1 @@ +{ "Keys": [ "Rocket", "Starbuster" ] } diff --git a/Tests/QtAutogen/mocPlugin/StyleB.hpp b/Tests/QtAutogen/mocPlugin/StyleB.hpp index ba89127..163c9b2 100644 --- a/Tests/QtAutogen/mocPlugin/StyleB.hpp +++ b/Tests/QtAutogen/mocPlugin/StyleB.hpp @@ -1,6 +1,7 @@ #ifndef STYLEB_HPP #define STYLEB_HPP +#include "StyleCommon.hpp" #include class StyleB : public QStylePlugin @@ -8,6 +9,7 @@ class StyleB : public QStylePlugin Q_OBJECT // Json file in local subdirectory Q_PLUGIN_METADATA(IID "org.styles.B" FILE "jsonIn/StyleB.json") + A_CUSTOM_MACRO(SomeArg, "jsonIn/StyleB_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/mocPlugin/StyleC.hpp b/Tests/QtAutogen/mocPlugin/StyleC.hpp index 9f71d75..52a887a 100644 --- a/Tests/QtAutogen/mocPlugin/StyleC.hpp +++ b/Tests/QtAutogen/mocPlugin/StyleC.hpp @@ -1,6 +1,7 @@ #ifndef STYLEC_HPP #define STYLEC_HPP +#include "StyleCommon.hpp" #include class StyleC : public QStylePlugin @@ -8,6 +9,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) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/mocPlugin/StyleCommon.hpp b/Tests/QtAutogen/mocPlugin/StyleCommon.hpp new file mode 100644 index 0000000..f1a7ec6 --- /dev/null +++ b/Tests/QtAutogen/mocPlugin/StyleCommon.hpp @@ -0,0 +1,7 @@ +#ifndef STYLECOMMON_HPP +#define STYLECOMMON_HPP + +// Empty test macro definition +#define A_CUSTOM_MACRO(name, jsonFile, pluginRegistrations) + +#endif diff --git a/Tests/QtAutogen/mocPlugin/StyleD.hpp b/Tests/QtAutogen/mocPlugin/StyleD.hpp index e58444d..df8a439 100644 --- a/Tests/QtAutogen/mocPlugin/StyleD.hpp +++ b/Tests/QtAutogen/mocPlugin/StyleD.hpp @@ -1,6 +1,7 @@ #ifndef STYLED_HPP #define STYLED_HPP +#include "StyleCommon.hpp" #include class StyleD : public QStylePlugin @@ -8,6 +9,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) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/mocPlugin/StyleE.hpp b/Tests/QtAutogen/mocPlugin/StyleE.hpp index 80e0b79..e7915a8 100644 --- a/Tests/QtAutogen/mocPlugin/StyleE.hpp +++ b/Tests/QtAutogen/mocPlugin/StyleE.hpp @@ -1,6 +1,7 @@ #ifndef STYLEE_HPP #define STYLEE_HPP +#include "StyleCommon.hpp" #include class StyleE : public QStylePlugin @@ -8,6 +9,7 @@ class StyleE : public QStylePlugin Q_OBJECT // No Json file Q_PLUGIN_METADATA(IID "org.styles.E") + A_CUSTOM_MACRO(SomeArg, InvalidFileArg, AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json b/Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json new file mode 100644 index 0000000..129cac4 --- /dev/null +++ b/Tests/QtAutogen/mocPlugin/jsonIn/StyleB_Custom.json @@ -0,0 +1 @@ +{ "Keys": [ "Rocket", "StarbusterB" ] } -- cgit v0.12 From 96f6f392e3d2ba95c11d0b77fbb5da485e626ed4 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 23 Feb 2017 13:50:29 +0100 Subject: Autogen: Add AUTOMOC_DEPEND_FILTERS documentation --- Help/manual/cmake-properties.7.rst | 1 + Help/manual/cmake-qt.7.rst | 3 ++ Help/manual/cmake-variables.7.rst | 1 + Help/prop_tgt/AUTOMOC.rst | 3 ++ Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst | 45 ++++++++++++++++++++++++++ Help/release/dev/Autogen_depends.rst | 10 ++++++ Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst | 12 +++++++ 7 files changed, 75 insertions(+) create mode 100644 Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst create mode 100644 Help/release/dev/Autogen_depends.rst create mode 100644 Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 5fad10c..a3b6e6b 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -115,6 +115,7 @@ Properties on Targets /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG /prop_tgt/ARCHIVE_OUTPUT_NAME /prop_tgt/AUTOGEN_TARGET_DEPENDS + /prop_tgt/AUTOMOC_DEPEND_FILTERS /prop_tgt/AUTOMOC_MOC_OPTIONS /prop_tgt/AUTOMOC /prop_tgt/AUTOUIC diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index e9da396..3b9931e 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -87,6 +87,9 @@ following targets by setting the :variable:`CMAKE_AUTOMOC` variable. The options to pass to ``moc``. The :variable:`CMAKE_AUTOMOC_MOC_OPTIONS` variable may be populated to pre-set the options for all following targets. +Additional ``moc`` dependency file names can be extracted from source code +by using :prop_tgt:`AUTOMOC_DEPEND_FILTERS`. + Source C++ files can be excluded from :prop_tgt:`AUTOMOC` processing by enabling :prop_sf:`SKIP_AUTOMOC` or the broader :prop_sf:`SKIP_AUTOGEN`. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 6112e65..259d87b 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -256,6 +256,7 @@ Variables that Control the Build /variable/CMAKE_ANDROID_STL_TYPE /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG + /variable/CMAKE_AUTOMOC_DEPEND_FILTERS /variable/CMAKE_AUTOMOC_MOC_OPTIONS /variable/CMAKE_AUTOMOC /variable/CMAKE_AUTORCC diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 4ac9b6e..b729c0b 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -57,6 +57,9 @@ See the documentation for this variable for more details. The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the automoc targets together in an IDE, e.g. in MSVS. +Additional ``moc`` dependency file names can be extracted from source code +by using :prop_tgt:`AUTOMOC_DEPEND_FILTERS`. + Source C++ files can be excluded from :prop_tgt:`AUTOMOC` processing by enabling :prop_sf:`SKIP_AUTOMOC` or the broader :prop_sf:`SKIP_AUTOGEN`. diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst new file mode 100644 index 0000000..810cbf4 --- /dev/null +++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst @@ -0,0 +1,45 @@ +AUTOMOC_DEPEND_FILTERS +---------------------- + +Filter definitions used by :prop_tgt:`AUTOMOC` to extract file names from +source code as additional dependencies for the ``moc`` file. + +This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON`` +for this target. + +Filters are defined as ``KEYWORD;REGULAR_EXPRESSION`` pairs. First the file +content is searched for ``KEYWORD``. If it is found at least once, then file +names are extracted by successively searching for ``REGULAR_EXPRESSION`` and +taking the first match group. + +Consider a filter extracts the file name ``DEP`` from the content of a file +``FOO``. If ``DEP`` changes, then the ``moc`` file for ``FOO`` gets rebuilt. +The file ``DEP`` is searched for first in the vicinity +of ``FOO`` and afterwards in the target's :prop_tgt:`INCLUDE_DIRECTORIES`. + +By default :prop_tgt:`AUTOMOC_DEPEND_FILTERS` is initialized from +:variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. + + +Example +------- + +Consider a file ``FOO.hpp`` holds a custom macro ``OBJ_JSON_FILE`` and we +want the ``moc`` file to depend on the macro`s file name argument:: + + class My_Class : public QObject + { + Q_OBJECT + OBJ_JSON_FILE ( "DEP.json" ) + ... + }; + +Then we might use :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS` to +define a filter like this:: + + set(CMAKE_AUTOMOC_DEPEND_FILTERS + "OBJ_JSON_FILE" "[\n][ \t]*OBJ_JSON_FILE[ \t]*\\([ \t]*\"([^\"]+)\"" + ) diff --git a/Help/release/dev/Autogen_depends.rst b/Help/release/dev/Autogen_depends.rst new file mode 100644 index 0000000..c774386 --- /dev/null +++ b/Help/release/dev/Autogen_depends.rst @@ -0,0 +1,10 @@ +AutoGen depends +--------------- + +* Variable :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS` was introduced to + allow :variable:`CMAKE_AUTOMOC` to extract additional dependency file names + for ``moc`` from the contents of source files. + +* The new target property :prop_tgt:`AUTOMOC_DEPEND_FILTERS` was introduced to + allow :prop_tgt:`AUTOMOC` to extract additional dependency file names + for ``moc`` from the contents of source files. diff --git a/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst b/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst new file mode 100644 index 0000000..5c3662d --- /dev/null +++ b/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst @@ -0,0 +1,12 @@ +CMAKE_AUTOMOC_DEPEND_FILTERS +---------------------------- + +Filter definitions used by :variable:`CMAKE_AUTOMOC` +to extract file names from source code as additional dependencies +for the ``moc`` file. + +This variable is used to initialize the :prop_tgt:`AUTOMOC_DEPEND_FILTERS` +property on all the targets. See that target property for additional +information. + +By default it is empty. -- cgit v0.12 From e98465cfed68f6511af552ac8ab0d168791f4302 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 22 Feb 2017 20:08:53 +0100 Subject: Autogen: Add Quote function and use it for logging --- Source/cmQtAutoGenerators.cxx | 124 +++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 51 deletions(-) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index e1b4f35..8d65129 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -36,6 +36,25 @@ static const char* SettingsKeyRcc = "AM_RCC_OLD_SETTINGS"; // -- Static functions +/** + * @brief Returns a the string escaped and enclosed in quotes + */ +static std::string Quoted(const std::string& text) +{ + static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a", + "\b", "\\b", "\f", "\\f", "\n", "\\n", + "\r", "\\r", "\t", "\\t", "\v", "\\v" }; + + std::string res = text; + for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep); + it += 2) { + cmSystemTools::ReplaceString(res, *it, *(it + 1)); + } + res = '"' + res; + res += '"'; + return res; +} + static std::string GetConfigDefinition(cmMakefile* makefile, const std::string& key, const std::string& config) @@ -273,8 +292,8 @@ bool cmQtAutoGenerators::MocDependFilterPush(const std::string& key, success = true; } else { this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Compiling " - "regular expression failed.\nKey: \"" + - key + "\"\nReg. exp.: \"" + regExp + "\""); + "regular expression failed.\nKey: " + + Quoted(key) + "\nExp.: " + Quoted(regExp)); } } else { this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Regular " @@ -320,8 +339,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( } // Check Qt version if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) { - this->LogError("AutoGen: Error: Unsupported Qt version: \"" + - this->QtMajorVersion + "\""); + this->LogError("AutoGen: Error: Unsupported Qt version: " + + Quoted(this->QtMajorVersion)); return false; } @@ -719,13 +738,13 @@ void cmQtAutoGenerators::MocFindDepends( if (!incFile.empty()) { mocDepends[absFilename].insert(incFile); if (this->Verbose) { - this->LogInfo("AutoMoc: Found dependency:\n \"" + absFilename + - "\"\n \"" + incFile + "\""); + this->LogInfo("AutoMoc: Found dependency:\n " + + Quoted(absFilename) + "\n " + Quoted(incFile)); } } else { - this->LogWarning("AutoMoc: Warning: \"" + absFilename + "\"\n" + - "Could not find dependency file \"" + match + - "\""); + this->LogWarning("AutoMoc: Warning: " + Quoted(absFilename) + + "\n" + "Could not find dependency file " + + Quoted(match)); } } contentChars += filter.regExp.end(); @@ -878,9 +897,11 @@ bool cmQtAutoGenerators::MocParseSourceContent( } else { std::ostringstream ost; ost << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << incString - << "\", but could not find header \"" << incRealBasename << '{' - << JoinExts(this->HeaderExtensions) << "}\"\n"; + << "The file includes the moc file " << Quoted(incString) + << ", but could not find header " + << Quoted(incRealBasename + "{" + + JoinExts(this->HeaderExtensions) + "}"); + ; this->LogError(ost.str()); return false; } @@ -902,32 +923,33 @@ bool cmQtAutoGenerators::MocParseSourceContent( fileToMoc = headerToMoc; if (!requiresMoc && (incBasename == scannedFileBasename)) { std::ostringstream ost; - ost << "AutoMoc: Warning: " << absFilename << "\n" - << "The file includes the moc file \"" << incString << "\"" + ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" + << "The file includes the moc file " << Quoted(incString) << ", but does not contain a Q_OBJECT or Q_GADGET macro.\n" - << "Running moc on \"" << headerToMoc << "\"!\n" - << "Include \"moc_" << incBasename - << ".cpp\" for a compatibility with " - "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"; + << "Running moc on " << Quoted(headerToMoc) << "!\n" + << "Include " << Quoted("moc_" + incBasename + ".cpp") + << " for a compatibility with strict mode (see " + "CMAKE_AUTOMOC_RELAXED_MODE).\n"; this->LogWarning(ost.str()); } else { std::ostringstream ost; - ost << "AutoMoc: Warning: " << absFilename << "\n" - << "The file includes the moc file \"" << incString - << "\" instead of \"moc_" << incBasename << ".cpp\".\n" - << "Running moc on \"" << headerToMoc << "\"!\n" - << "Include \"moc_" << incBasename - << ".cpp\" for compatibility with " - "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"; + ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" + << "The file includes the moc file " << Quoted(incString) + << " instead of " << Quoted("moc_" + incBasename + ".cpp") + << ".\n" + << "Running moc on " << Quoted(headerToMoc) << "!\n" + << "Include " << Quoted("moc_" + incBasename + ".cpp") + << " for compatibility with strict mode (see " + "CMAKE_AUTOMOC_RELAXED_MODE).\n"; this->LogWarning(ost.str()); } } else { std::ostringstream ost; - ost << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << incString - << "\", which seems to be the moc file from a different " + ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" + << "The file includes the moc file " << Quoted(incString) + << ". which seems to be the moc file from a different " "source file. CMake also could not find a matching " - "header.\n"; + "header."; this->LogError(ost.str()); return false; } @@ -941,21 +963,21 @@ bool cmQtAutoGenerators::MocParseSourceContent( // Accept but issue a warning if moc isn't required if (!requiresMoc) { std::ostringstream ost; - ost << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << incString << "\"" + ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" + << "The file includes the moc file " << Quoted(incString) << ", but does not contain a Q_OBJECT or Q_GADGET " - "macro.\n"; + "macro."; this->LogWarning(ost.str()); } } else { // Don't allow FOO.moc include other than self in strict mode std::ostringstream ost; - ost << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << incString - << "\", which seems to be the moc file from a different " - "source file. This is not supported. Include \"" - << scannedFileBasename - << ".moc\" to run moc on this source file.\n"; + ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" + << "The file includes the moc file " << Quoted(incString) + << ", which seems to be the moc file from a different " + "source file. This is not supported. Include " + << Quoted(scannedFileBasename + ".moc") + << " to run moc on this source file."; this->LogError(ost.str()); return false; } @@ -978,15 +1000,15 @@ bool cmQtAutoGenerators::MocParseSourceContent( if (relaxed && !ownMocUnderscoreInclude.empty()) { // This is for KDE4 compatibility: std::ostringstream ost; - ost << "AutoMoc: Warning: " << absFilename << "\n" + ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" << "The file contains a " << macroName << " macro, but does not include " - << "\"" << scannedFileBasename << ".moc\", but instead includes " - << "\"" << ownMocUnderscoreInclude << "\".\n" - << "Running moc on \"" << absFilename << "\"!\n" - << "Better include \"" << scannedFileBasename - << ".moc\" for compatibility with " - "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"; + << Quoted(scannedFileBasename + ".moc") << ", but instead includes " + << Quoted(ownMocUnderscoreInclude) << ".\n" + << "Running moc on " << Quoted(absFilename) << "!\n" + << "Better include " << Quoted(scannedFileBasename + ".moc") + << " for compatibility with strict mode (see " + "CMAKE_AUTOMOC_RELAXED_MODE)."; this->LogWarning(ost.str()); // Use scanned source file instead of scanned header file as moc source @@ -997,10 +1019,10 @@ bool cmQtAutoGenerators::MocParseSourceContent( } else { // Otherwise always error out since it will not compile: std::ostringstream ost; - ost << "AutoMoc: Error: " << absFilename << "\n" + ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" << "The file contains a " << macroName << " macro, but does not include " - << "\"" << scannedFileBasename << ".moc\"!\n"; + << Quoted(scannedFileBasename + ".moc") << "!"; this->LogError(ost.str()); return false; } @@ -1280,7 +1302,7 @@ bool cmQtAutoGenerators::MocGenerateFile( { std::ostringstream ost; ost << "AutoMoc: Error: moc process failed for\n"; - ost << "\"" << mocFileRel << "\"\n"; + ost << Quoted(mocFileRel) << "\n"; ost << "AutoMoc: Command:\n" << cmJoin(cmd, " ") << "\n"; ost << "AutoMoc: Command output:\n" << output << "\n"; this->LogError(ost.str()); @@ -1419,8 +1441,8 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, { std::ostringstream ost; ost << "AutoUic: Error: uic process failed for\n"; - ost << "\"" << uicFileRel << "\" needed by\n"; - ost << "\"" << realName << "\"\n"; + ost << Quoted(uicFileRel) << " needed by\n"; + ost << Quoted(realName) << "\n"; ost << "AutoUic: Command:\n" << cmJoin(cmd, " ") << "\n"; ost << "AutoUic: Command output:\n" << output << "\n"; this->LogError(ost.str()); @@ -1558,7 +1580,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, { std::ostringstream ost; ost << "AutoRcc: Error: rcc process failed for\n"; - ost << "\"" << rccOutputFile << "\"\n"; + ost << Quoted(rccOutputFile) << "\n"; ost << "AutoRcc: Command:\n" << cmJoin(cmd, " ") << "\n"; ost << "AutoRcc: Command output:\n" << output << "\n"; this->LogError(ost.str()); -- cgit v0.12 From 62a1e292f29d740d0b193e45f0acd37f7ffaced6 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 22 Feb 2017 20:16:44 +0100 Subject: Autogen: Add hint to SKIP_AUTOMOC in error message Closes #15751 --- Source/cmQtAutoGenerators.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 8d65129..e7e456a 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1022,7 +1022,9 @@ bool cmQtAutoGenerators::MocParseSourceContent( ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" << "The file contains a " << macroName << " macro, but does not include " - << Quoted(scannedFileBasename + ".moc") << "!"; + << Quoted(scannedFileBasename + ".moc") << "!\n" + << "Consider adding the include or enabling SKIP_AUTOMOC for this " + "file."; this->LogError(ost.str()); return false; } -- cgit v0.12