Merge topic 'autogen-macro-names2'

93c8d55d Autogen: Update (CMAKE_)AUTOMOC_MACRO_NAMES release notes
084ace47 Autogen: Tests: Update AUTOMOC_MACRO_NAMES test
08041dd1 Autogen: Doc: Update documentation for (CMAKE_)AUTOMOC_MACRO_NAMES
7b33d67b Autogen: Create info file directory before writing
786b5be0 Autogen: Define all macro names in CMAKE_AUTOMOC_MACRO_NAMES

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1321
This commit is contained in:
Brad King 2017-09-29 12:52:43 +00:00 committed by Kitware Robot
commit 194dd9ea8b
23 changed files with 193 additions and 98 deletions

View File

@ -59,9 +59,10 @@ The :prop_tgt:`AUTOMOC` target property controls whether :manual:`cmake(1)`
inspects the C++ files in the target to determine if they require ``moc`` to
be run, and to create rules to execute ``moc`` at the appropriate time.
If a ``Q_OBJECT`` or ``Q_GADGET`` macro is found in a header file, ``moc``
will be run on the file. The result will be put into a file named according
to ``moc_<basename>.cpp``. If the macro is found in a C++ implementation
If a macro from :prop_tgt:`AUTOMOC_MACRO_NAMES` is found in a header file,
``moc`` will be run on the file. The result will be put into a file named
according to ``moc_<basename>.cpp``.
If the macro is found in a C++ implementation
file, the moc output will be put into a file named according to
``<basename>.moc``, following the Qt conventions. The ``<basename>.moc`` must
be included by the user in the C++ implementation file with a preprocessor
@ -95,9 +96,7 @@ 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 macro names to search for can be added to :prop_tgt:`AUTOMOC_MACRO_NAMES`.
Additional ``moc`` dependency file names can be extracted from source code
by using :prop_tgt:`AUTOMOC_DEPEND_FILTERS`.

View File

@ -12,8 +12,8 @@ When this property is set ``ON``, CMake will scan the header and
source files at build time and invoke moc accordingly.
* If an ``#include`` statement like ``#include "moc_<basename>.cpp"`` is found,
the ``Q_OBJECT`` or ``Q_GADGET`` macros are expected in an otherwise empty
line of the ``<basename>.h(xx)`` header file. ``moc`` is run on the header
a macro from :prop_tgt:`AUTOMOC_MACRO_NAMES` is expected to appear in the
``<basename>.h(xx)`` header file. ``moc`` is run on the header
file to generate ``moc_<basename>.cpp`` in the
``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added
to the target's :prop_tgt:`INCLUDE_DIRECTORIES`.
@ -26,11 +26,12 @@ source files at build time and invoke moc accordingly.
* See :prop_tgt:`AUTOGEN_BUILD_DIR`.
* If an ``#include`` statement like ``#include "<basename>.moc"`` is found,
then ``Q_OBJECT`` or ``Q_GADGET`` macros are expected in the current source
file and ``moc`` is run on the source file itself.
a macro from :prop_tgt:`AUTOMOC_MACRO_NAMES` is expected to appear in the
source file and ``moc`` is run on the source file itself.
* Header files that are not included by an ``#include "moc_<basename>.cpp"``
statement are nonetheless scanned for ``Q_OBJECT`` or ``Q_GADGET`` macros.
statement are nonetheless scanned for a macro out of
:prop_tgt:`AUTOMOC_MACRO_NAMES`.
The resulting ``moc_<basename>.cpp`` files are generated in custom
directories and automatically included in a generated
``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` file,
@ -44,8 +45,9 @@ source files at build time and invoke moc accordingly.
* Additionally, header files with the same base name as a source file,
(like ``<basename>.h``) or ``_p`` appended to the base name (like
``<basename>_p.h``), are parsed for ``Q_OBJECT`` or ``Q_GADGET`` macros,
and if found, ``moc`` is also executed on those files.
``<basename>_p.h``), are scanned for a macro out of
:prop_tgt:`AUTOMOC_MACRO_NAMES`, and if found, ``moc``
is also executed on those files.
* ``AUTOMOC`` always checks multiple header alternative extensions,
such as ``hpp``, ``hxx``, etc. when searching for headers.
@ -69,9 +71,7 @@ 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 macro names to search for can be added to :prop_tgt:`AUTOMOC_MACRO_NAMES`.
Additional ``moc`` dependency file names can be extracted from source code
by using :prop_tgt:`AUTOMOC_DEPEND_FILTERS`.

View File

@ -1,20 +1,23 @@
AUTOMOC_MACRO_NAMES
-------------------
Additional macro names used by :prop_tgt:`AUTOMOC`
to determine if a C++ file needs to be processed by ``moc``.
A :ref:`;-list <CMake Language Lists>` list of 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.
When running :prop_tgt:`AUTOMOC`, CMake searches for the strings listed in
:prop_tgt:`AUTOMOC_MACRO_NAMES` in C++ source and header files.
If any of the strings is found
- as the first non space string on a new line or
- as the first non space string after a ``{`` on a new line,
then the file will be processed by ``moc``.
By default :prop_tgt:`AUTOMOC_MACRO_NAMES` is initialized from
:variable:`CMAKE_AUTOMOC_MACRO_NAMES`, which is empty by default.
:variable:`CMAKE_AUTOMOC_MACRO_NAMES`.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.
@ -25,4 +28,4 @@ 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")
set_property(TARGET tgt APPEND PROPERTY AUTOMOC_MACRO_NAMES "CUSTOM_MACRO")

View File

@ -1,12 +1,14 @@
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``,
``Q_GADGET`` or ``Q_NAMESPACE`` 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.
* When using :prop_tgt:`AUTOMOC`, CMake searches for the strings ``Q_OBJECT``,
``Q_GADGET`` or ``Q_NAMESPACE`` 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.

View File

@ -1,14 +1,15 @@
CMAKE_AUTOMOC_MACRO_NAMES
----------------------------
Additional macro names used by :variable:`CMAKE_AUTOMOC`
to determine if a C++ file needs to be processed by ``moc``.
A :ref:`;-list <CMake Language Lists>` list of 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.
The default value is ``Q_OBJECT;Q_GADGET;Q_NAMESPACE``.
Example
-------
@ -16,4 +17,4 @@ 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")
list(APPEND CMAKE_AUTOMOC_MACRO_NAMES "CUSTOM_MACRO")

View File

@ -23,6 +23,7 @@ set(CMAKE_DL_LIBS "dl")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE")
# basically all general purpose OSs support shared libs
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)

View File

@ -613,6 +613,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator();
std::string const autogenTargetName = GetAutogenTargetName(target);
std::string const autogenInfoDir = GetAutogenTargetFilesDir(target);
std::string const autogenBuildDir = GetAutogenTargetBuildDir(target);
std::string const workingDirectory =
cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory());
@ -630,8 +631,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
AddCleanFile(makefile, autogenBuildDir);
// Remove old settings on cleanup
{
std::string base = GetAutogenTargetFilesDir(target);
base += "/AutogenOldSettings";
std::string base = autogenInfoDir + "/AutogenOldSettings";
if (multiConfig == cmQtAutoGen::SINGLE) {
AddCleanFile(makefile, base.append(".cmake"));
} else {
@ -652,7 +652,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
currentLine.push_back(cmSystemTools::GetCMakeCommand());
currentLine.push_back("-E");
currentLine.push_back("cmake_autogen");
currentLine.push_back(GetAutogenTargetFilesDir(target));
currentLine.push_back(autogenInfoDir);
currentLine.push_back("$<CONFIGURATION>");
commandLines.push_back(currentLine);
}
@ -1097,8 +1097,13 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
// Generate info file
{
std::string infoFile = GetAutogenTargetFilesDir(target);
infoFile += "/AutogenInfo.cmake";
std::string const infoDir = GetAutogenTargetFilesDir(target);
if (!cmSystemTools::MakeDirectory(infoDir)) {
std::string emsg = ("Could not create directory: ");
emsg += cmQtAutoGen::Quoted(infoDir);
cmSystemTools::Error(emsg.c_str());
}
std::string const infoFile = infoDir + "/AutogenInfo.cmake";
{
std::string infoFileIn = cmSystemTools::GetCMakeRoot();
infoFileIn += "/Modules/AutogenInfo.cmake.in";

View File

@ -149,12 +149,6 @@ cmQtAutoGenerators::cmQtAutoGenerators()
}
}
// Moc macro filters
this->MocMacroFilters.emplace_back(
"Q_OBJECT", "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]");
this->MocMacroFilters.emplace_back(
"Q_GADGET", "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]");
// Precompile regular expressions
this->MocRegExpInclude.compile(
"[\n][ \t]*#[ \t]*include[ \t]+"
@ -326,7 +320,7 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile,
InfoGetList("AM_MOC_MACRO_NAMES");
for (std::string const& item : MocMacroNames) {
this->MocMacroFilters.emplace_back(
item, ("[^a-zA-Z0-9_]" + item).append("[^a-zA-Z0-9_]"));
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
}
}
{

View File

@ -65,15 +65,6 @@ add_executable(mocOnly mocOnlySource/main.cpp mocOnlySource/StyleA.cpp mocOnlySo
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)
@ -188,8 +179,10 @@ set_property(TARGET skipRccB PROPERTY AUTOMOC ON)
target_link_libraries(skipRccB ${QT_LIBRARIES})
# -- Test
# Source files with the same basename in different subdirectories
add_subdirectory(sameName)
# MOC AUTOMOC_MACRO_NAMES
if (NOT QT_TEST_VERSION STREQUAL 4)
add_subdirectory(mocMacroName)
endif()
# -- Test
# Tests AUTOMOC with generated sources
@ -216,6 +209,10 @@ add_subdirectory(uicInclude)
# OBJECT libraries
add_subdirectory(objectLibrary)
# -- Test
# Source files with the same basename in different subdirectories
add_subdirectory(sameName)
# -- Test
# Complex test case
add_subdirectory(complex)

View File

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.9)
list(APPEND CMAKE_AUTOMOC_MACRO_NAMES "QO1_ALIAS")
add_executable(mmn main.cpp Gadget.cpp Object.cpp Object1Aliased.cpp Object2Aliased.cpp)
set_property(TARGET mmn PROPERTY AUTOMOC ON)
set_property(TARGET mmn APPEND PROPERTY AUTOMOC_MACRO_NAMES "QO2_ALIAS")
target_link_libraries(mmn ${QT_LIBRARIES})

View File

@ -0,0 +1,8 @@
#ifndef CUSTOM_MACROS_HPP
#define CUSTOM_MACROS_HPP
#include <QObject>
#define QO1_ALIAS Q_OBJECT
#define QO2_ALIAS Q_OBJECT
#endif

View File

@ -0,0 +1,6 @@
#include "Gadget.hpp"
Gadget::Gadget()
: test(0)
{
}

View File

@ -0,0 +1,15 @@
#ifndef GADGET_HPP
#define GADGET_HPP
#include <QMetaType>
class Gadget
{
Q_GADGET
Q_PROPERTY(int test MEMBER test)
public:
Gadget();
int test;
};
#endif

View File

@ -1,7 +0,0 @@
#ifndef MACROALIAS_HPP
#define MACROALIAS_HPP
#include <QObject>
#define QO_ALIAS Q_OBJECT
#endif

View File

@ -1,9 +0,0 @@
#include "MacroName.hpp"
MacroName::MacroName()
{
}
void MacroName::aSlot()
{
}

View File

@ -1,20 +0,0 @@
#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

View File

@ -0,0 +1,9 @@
#include "Object.hpp"
Object::Object()
{
}
void Object::aSlot()
{
}

View File

@ -0,0 +1,19 @@
#ifndef OBJECT_HPP
#define OBJECT_HPP
#include <QObject>
class Object : public QObject
{
Q_OBJECT
Q_PROPERTY(int test MEMBER test)
public:
Object();
Q_SLOT
void aSlot();
int test;
};
#endif

View File

@ -0,0 +1,9 @@
#include "Object1Aliased.hpp"
Object1Aliased::Object1Aliased()
{
}
void Object1Aliased::aSlot()
{
}

View File

@ -0,0 +1,20 @@
#ifndef OBJECTALIASED_HPP
#define OBJECTALIASED_HPP
#include "CustomMacros.hpp"
// Test Qt object macro hidden in a macro (AUTOMOC_MACRO_NAMES)
class Object1Aliased : public QObject
{
QO1_ALIAS
public:
Object1Aliased();
signals:
void aSignal();
public slots:
void aSlot();
};
#endif

View File

@ -0,0 +1,9 @@
#include "Object2Aliased.hpp"
Object2Aliased::Object2Aliased()
{
}
void Object2Aliased::aSlot()
{
}

View File

@ -0,0 +1,20 @@
#ifndef OBJECT2ALIASED_HPP
#define OBJECT2ALIASED_HPP
#include "CustomMacros.hpp"
// Test Qt object macro hidden in a macro (AUTOMOC_MACRO_NAMES)
class Object2Aliased : public QObject
{
QO2_ALIAS
public:
Object2Aliased();
signals:
void aSignal();
public slots:
void aSlot();
};
#endif

View File

@ -1,7 +1,13 @@
#include "MacroName.hpp"
#include "Gadget.hpp"
#include "Object.hpp"
#include "Object1Aliased.hpp"
#include "Object2Aliased.hpp"
int main(int argv, char** args)
{
MacroName macroName;
Gadget gadget;
Object object;
Object1Aliased object1Aliased;
Object2Aliased object2Aliased;
return 0;
}