From 93f0ba2823b694340e6cfdb4e6befbf7fcf520bd Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Fri, 18 Aug 2017 11:11:21 +0200 Subject: Autogen: Add AUTOMOC_MACRO_NAMES support Closes #17176 --- Modules/AutogenInfo.cmake.in | 1 + Source/cmQtAutoGeneratorInitializer.cxx | 2 ++ Source/cmQtAutoGenerators.cxx | 28 +++++++++++++++++++--------- Source/cmQtAutoGenerators.h | 2 +- Source/cmTarget.cxx | 1 + 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 4e85474..e1a9c39 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -18,6 +18,7 @@ set(AM_MOC_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_MACRO_NAMES @_moc_macro_names@) set(AM_MOC_DEPEND_FILTERS @_moc_depend_filters@) set(AM_MOC_PREDEFS_CMD @_moc_predefs_cmd@) # UIC settings diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 7974977..6ae101f 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -380,6 +380,8 @@ static void MocSetupAutoTarget( AddDefinitionEscaped(makefile, "_moc_relaxed_mode", makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE") ? "TRUE" : "FALSE"); + AddDefinitionEscaped(makefile, "_moc_macro_names", + GetSafeProperty(target, "AUTOMOC_MACRO_NAMES")); AddDefinitionEscaped(makefile, "_moc_depend_filters", GetSafeProperty(target, "AUTOMOC_DEPEND_FILTERS")); diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 1fe07ce..65ea048 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -280,12 +280,10 @@ cmQtAutoGenerators::cmQtAutoGenerators() } // Moc macro filters - this->MocMacroFilters[0].first = "Q_OBJECT"; - this->MocMacroFilters[0].second.compile( - "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]"); - this->MocMacroFilters[1].first = "Q_GADGET"; - this->MocMacroFilters[1].second.compile( - "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]"); + this->MocMacroFilters.push_back( + MocMacroFilter("Q_OBJECT", "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]")); + this->MocMacroFilters.push_back( + MocMacroFilter("Q_GADGET", "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]")); // Precompile regular expressions this->MocRegExpInclude.compile( @@ -402,7 +400,6 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable); InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable); - InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd); // Check Qt version if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) { this->LogError("AutoGen: Error: Unsupported Qt version: " + @@ -427,6 +424,16 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions); InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode); { + std::vector MocMacroNames; + InfoGet(makefile, "AM_MOC_MACRO_NAMES", MocMacroNames); + for (std::vector::const_iterator dit = + MocMacroNames.begin(); + dit != MocMacroNames.end(); ++dit) { + this->MocMacroFilters.push_back( + MocMacroFilter(*dit, "[^a-zA-Z0-9_]" + *dit + "[^a-zA-Z0-9_]")); + } + } + { std::vector mocDependFilters; InfoGet(makefile, "AM_MOC_DEPEND_FILTERS", mocDependFilters); // Insert Q_PLUGIN_METADATA dependency filter @@ -452,6 +459,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( return false; } } + InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd); } // - Uic @@ -800,8 +808,10 @@ bool cmQtAutoGenerators::RunAutogen() bool cmQtAutoGenerators::MocRequired(const std::string& contentText, std::string* macroName) { - for (unsigned int ii = 0; ii != cmArraySize(this->MocMacroFilters); ++ii) { - MocMacroFilter& filter = this->MocMacroFilters[ii]; + for (std::vector::iterator fit = + this->MocMacroFilters.begin(); + fit != this->MocMacroFilters.end(); ++fit) { + MocMacroFilter& filter = *fit; // Run a simple find string operation before the expensive // regular expression check if (contentText.find(filter.first) != std::string::npos) { diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 337aa17..ce5db4a 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -201,7 +201,7 @@ private: std::vector MocOptions; std::vector MocPredefsCmd; std::vector MocDependFilters; - MocMacroFilter MocMacroFilters[2]; + std::vector MocMacroFilters; cmsys::RegularExpression MocRegExpInclude; // -- Uic bool UicSettingsChanged; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c1b6f97..501aebf 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -248,6 +248,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("AUTOUIC", CM_NULLPTR); this->SetPropertyDefault("AUTORCC", CM_NULLPTR); this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", CM_NULLPTR); + this->SetPropertyDefault("AUTOMOC_MACRO_NAMES", CM_NULLPTR); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", CM_NULLPTR); this->SetPropertyDefault("AUTOUIC_OPTIONS", CM_NULLPTR); this->SetPropertyDefault("AUTOUIC_SEARCH_PATHS", CM_NULLPTR); -- cgit v0.12 From 05891d8f774cc2ac3fea44f6f320dcdc2e1d95e2 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Fri, 18 Aug 2017 12:29:50 +0200 Subject: Autogen: Add test for AUTOMOC_MACRO_NAMES --- Tests/QtAutogen/CMakeLists.txt | 9 +++++++++ Tests/QtAutogen/mocMacroName/MacroAlias.hpp | 7 +++++++ Tests/QtAutogen/mocMacroName/MacroName.cpp | 9 +++++++++ Tests/QtAutogen/mocMacroName/MacroName.hpp | 20 ++++++++++++++++++++ Tests/QtAutogen/mocMacroName/main.cpp | 7 +++++++ 5 files changed, 52 insertions(+) create mode 100644 Tests/QtAutogen/mocMacroName/MacroAlias.hpp create mode 100644 Tests/QtAutogen/mocMacroName/MacroName.cpp create mode 100644 Tests/QtAutogen/mocMacroName/MacroName.hpp create mode 100644 Tests/QtAutogen/mocMacroName/main.cpp diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 198bf63..be864c3 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -66,6 +66,15 @@ set_property(TARGET mocOnly PROPERTY AUTOMOC ON) target_link_libraries(mocOnly ${QT_LIBRARIES}) # -- Test +# MOC AUTOMOC_MACRO_NAMES +if (NOT QT_TEST_VERSION STREQUAL 4) + add_executable(mocMacroName mocMacroName/main.cpp mocMacroName/MacroName.cpp) + set_property(TARGET mocMacroName PROPERTY AUTOMOC ON) + set_property(TARGET mocMacroName PROPERTY AUTOMOC_MACRO_NAMES "QO_ALIAS") + target_link_libraries(mocMacroName ${QT_LIBRARIES}) +endif() + +# -- Test # UIC only if(ALLOW_WRAP_CPP) qtx_wrap_cpp(uicOnlyMoc uicOnlySource/uiconly.h) diff --git a/Tests/QtAutogen/mocMacroName/MacroAlias.hpp b/Tests/QtAutogen/mocMacroName/MacroAlias.hpp new file mode 100644 index 0000000..cf06f2a --- /dev/null +++ b/Tests/QtAutogen/mocMacroName/MacroAlias.hpp @@ -0,0 +1,7 @@ +#ifndef MACROALIAS_HPP +#define MACROALIAS_HPP + +#include +#define QO_ALIAS Q_OBJECT + +#endif diff --git a/Tests/QtAutogen/mocMacroName/MacroName.cpp b/Tests/QtAutogen/mocMacroName/MacroName.cpp new file mode 100644 index 0000000..78d04a8 --- /dev/null +++ b/Tests/QtAutogen/mocMacroName/MacroName.cpp @@ -0,0 +1,9 @@ +#include "MacroName.hpp" + +MacroName::MacroName() +{ +} + +void MacroName::aSlot() +{ +} diff --git a/Tests/QtAutogen/mocMacroName/MacroName.hpp b/Tests/QtAutogen/mocMacroName/MacroName.hpp new file mode 100644 index 0000000..b6c7306 --- /dev/null +++ b/Tests/QtAutogen/mocMacroName/MacroName.hpp @@ -0,0 +1,20 @@ +#ifndef MACRONAME_HPP +#define MACRONAME_HPP + +#include "MacroAlias.hpp" + +// Test Qt object macro hidden in a macro (AUTOMOC_MACRO_NAMES) +class MacroName : public QObject +{ + QO_ALIAS +public: + MacroName(); + +signals: + void aSignal(); + +public slots: + void aSlot(); +}; + +#endif diff --git a/Tests/QtAutogen/mocMacroName/main.cpp b/Tests/QtAutogen/mocMacroName/main.cpp new file mode 100644 index 0000000..67ee81f --- /dev/null +++ b/Tests/QtAutogen/mocMacroName/main.cpp @@ -0,0 +1,7 @@ +#include "MacroName.hpp" + +int main(int argv, char** args) +{ + MacroName macroName; + return 0; +} -- cgit v0.12 From 7529d84facc8c5b3ddfc916c20c5998d6aa9acaf Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Fri, 18 Aug 2017 13:58:14 +0200 Subject: Autogen: Add documentation for AUTOMOC_MACRO_NAMES --- Help/manual/cmake-properties.7.rst | 1 + Help/manual/cmake-qt.7.rst | 4 ++++ Help/manual/cmake-variables.7.rst | 1 + Help/prop_tgt/AUTOMOC.rst | 14 +++++++++----- Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst | 28 ++++++++++++++++++++++++++++ Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst | 19 +++++++++++++++++++ 6 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst create mode 100644 Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index cc8c356..f1378c8 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -123,6 +123,7 @@ Properties on Targets /prop_tgt/AUTOGEN_BUILD_DIR /prop_tgt/AUTOGEN_TARGET_DEPENDS /prop_tgt/AUTOMOC_DEPEND_FILTERS + /prop_tgt/AUTOMOC_MACRO_NAMES /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 e345cd2..55121df 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -95,6 +95,10 @@ 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. +The appearance of the strings ``Q_OBJECT`` or ``Q_GADGET`` in a source file +determines if it needs to be ``moc`` processed. To search for additional +strings, list them in :prop_tgt:`AUTOMOC_MACRO_NAMES`. + Additional ``moc`` dependency file names can be extracted from source code by using :prop_tgt:`AUTOMOC_DEPEND_FILTERS`. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 363b90f..bef1171 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -270,6 +270,7 @@ Variables that Control the Build /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG /variable/CMAKE_AUTOMOC /variable/CMAKE_AUTOMOC_DEPEND_FILTERS + /variable/CMAKE_AUTOMOC_MACRO_NAMES /variable/CMAKE_AUTOMOC_MOC_OPTIONS /variable/CMAKE_AUTORCC /variable/CMAKE_AUTORCC_OPTIONS diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index e70fe0d..61813be68 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -5,8 +5,8 @@ Should the target be processed with automoc (for Qt projects). AUTOMOC is a boolean specifying whether CMake will handle the Qt ``moc`` preprocessor automatically, i.e. without having to use the -:module:`QT4_WRAP_CPP() ` or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are -supported. +:module:`QT4_WRAP_CPP() ` or QT5_WRAP_CPP() macro. +Currently Qt4 and Qt5 are supported. When this property is set ``ON``, CMake will scan the header and source files at build time and invoke moc accordingly. @@ -37,7 +37,7 @@ source files at build time and invoke moc accordingly. which is compiled as part of the target. * The custom directories with checksum - based names help to avoid name collisions for moc files with the same + based names help to avoid name collisions for ``moc`` files with the same ````. * See :prop_tgt:`AUTOGEN_BUILD_DIR`. @@ -56,11 +56,11 @@ source files at build time and invoke moc accordingly. This property is initialized by the value of the :variable:`CMAKE_AUTOMOC` variable if it is set when a target is created. -Additional command line options for moc can be set via the +Additional command line options for ``moc`` can be set via the :prop_tgt:`AUTOMOC_MOC_OPTIONS` property. By enabling the :variable:`CMAKE_AUTOMOC_RELAXED_MODE` variable the -rules for searching the files which will be processed by moc can be relaxed. +rules for searching the files which will be processed by ``moc`` can be relaxed. See the documentation for this variable for more details. The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the @@ -69,6 +69,10 @@ automoc targets together in an IDE, e.g. in MSVS. The global property :prop_gbl:`AUTOGEN_SOURCE_GROUP` can be used to group files generated by :prop_tgt:`AUTOMOC` together in an IDE, e.g. in MSVS. +The appearance of the strings ``Q_OBJECT`` or ``Q_GADGET`` in a source file +determines if it needs to be ``moc`` processed. To search for additional +strings, list them in :prop_tgt:`AUTOMOC_MACRO_NAMES`. + Additional ``moc`` dependency file names can be extracted from source code by using :prop_tgt:`AUTOMOC_DEPEND_FILTERS`. diff --git a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst new file mode 100644 index 0000000..0639bc8 --- /dev/null +++ b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst @@ -0,0 +1,28 @@ +AUTOMOC_MACRO_NAMES +------------------- + +Additional macro names used by :prop_tgt:`AUTOMOC` +to determine if a C++ file needs to be processed by ``moc``. + +This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON`` +for this target. + +CMake searches for the strings ``Q_OBJECT`` and ``Q_GADGET`` to +determine if a file needs to be processed by ``moc``. +:prop_tgt:`AUTOMOC_MACRO_NAMES` allows to add additional strings to the +search list. This is useful for cases where the ``Q_OBJECT`` or ``Q_GADGET`` +macro is hidden inside another macro. + +By default :prop_tgt:`AUTOMOC_MACRO_NAMES` is initialized from +:variable:`CMAKE_AUTOMOC_MACRO_NAMES`, which is empty by default. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. + +Example +------- +In this case the the ``Q_OBJECT`` macro is hidden inside an other macro +called ``CUSTOM_MACRO``. To let CMake know that source files, that contain +``CUSTOM_MACRO``, need to be ``moc`` processed, we call:: + + set_property(TARGET tgt PROPERTY AUTOMOC_MACRO_NAMES "CUSTOM_MACRO") diff --git a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst new file mode 100644 index 0000000..7ed3445 --- /dev/null +++ b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst @@ -0,0 +1,19 @@ +CMAKE_AUTOMOC_MACRO_NAMES +---------------------------- + +Additional macro names used by :variable:`CMAKE_AUTOMOC` +to determine if a C++ file needs to be processed by ``moc``. + +This variable is used to initialize the :prop_tgt:`AUTOMOC_MACRO_NAMES` +property on all the targets. See that target property for additional +information. + +By default it is empty. + +Example +------- +Let CMake know that source files that contain ``CUSTOM_MACRO`` must be ``moc`` +processed as well:: + + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTOMOC_MACRO_NAMES "CUSTOM_MACRO") -- cgit v0.12 From b3d98c6ec2c966b316ffeec257a249e8355ce005 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Fri, 18 Aug 2017 14:07:57 +0200 Subject: Autogen: Add release notes for AUTOMOC_MACRO_NAMES --- Help/release/dev/autogen-macro-names.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Help/release/dev/autogen-macro-names.rst diff --git a/Help/release/dev/autogen-macro-names.rst b/Help/release/dev/autogen-macro-names.rst new file mode 100644 index 0000000..736dd3a --- /dev/null +++ b/Help/release/dev/autogen-macro-names.rst @@ -0,0 +1,12 @@ +autogen-macro-names +------------------- + +* When using :prop_tgt:`AUTOMOC`, CMake searches for the strings ``Q_OBJECT`` + and ``Q_OBJECT`` in a source file to determine if it needs to be ``moc`` + processed. The new variable :variable:`CMAKE_AUTOMOC_MACRO_NAMES` allows to + register additional strings (macro names) so search for. + +* When using :prop_tgt:`AUTOMOC`, CMake searches for the strings ``Q_OBJECT`` + and ``Q_OBJECT`` in a source file to determine if it needs to be ``moc`` + processed. The new target property :prop_tgt:`AUTOMOC_MACRO_NAMES` allows to + register additional strings (macro names) so search for. -- cgit v0.12