Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \page moc.html
++ \title Using the Meta-Object Compiler (moc)
++ \ingroup qttools
++ \keyword moc
++
++ The Meta-Object Compiler, \c moc, is the program that handles
++ \l{Meta-Object System}{Qt's C++ extensions}.
++
++ The \c moc tool reads a C++ header file. If it finds one or more
++ class declarations that contain the Q_OBJECT macro, it
++ produces a C++ source file containing the meta-object code for
++ those classes. Among other things, meta-object code is required
++ for the signals and slots mechanism, the run-time type information,
++ and the dynamic property system.
++
++ The C++ source file generated by \c moc must be compiled and
++ linked with the implementation of the class.
++
++ Both \l qmake and \l {Build with CMake}{CMake} generate makefiles with
++ build rules that will invoke \c moc accordingly, so you will not need to use
++ the \c moc directly. \c qmake will add these build rules by default, whereas
++ with CMake, you can use the \l {CMake AUTOMOC Documentation}{AUTOMOC}
++ property to handle \c moc automatically. For more background information on
++ \c moc, see \l{Why Does Qt Use Moc for Signals and Slots?}
++
++ \section1 Usage
++
++ \c moc is typically used with an input file containing class
++ declarations like this:
++
++ \snippet snippets/moc/myclass1.h 0
++
++ In addition to the signals and slots shown above, \c moc also
++ implements object properties as in the next example. The
++ Q_PROPERTY() macro declares an object property, while
++ Q_ENUM() declares a list of enumeration types within the class
++ to be usable inside the \l{Qt's Property System}{property
++ system}.
++
++ In the following example, we declare a property of the
++ enumeration type \c Priority that is also called \c priority and
++ has a get function \c priority() and a set function \c
++ setPriority().
++
++ \snippet snippets/moc/myclass2.h 0
++
++ The Q_FLAG() macro declares enums that are to be used
++ as flags, i.e. OR'd together. Another macro, Q_CLASSINFO(),
++ allows you to attach additional name/value pairs to the class's
++ meta-object:
++
++ \snippet snippets/moc/myclass3.h 0
++
++ The output produced by \c moc must be compiled and linked, just
++ like the other C++ code in your program; otherwise, the build
++ will fail in the final link phase. If you use \c qmake, this is
++ done automatically. Whenever \c qmake is run, it parses the
++ project's header files and generates make rules to invoke \c moc
++ for those files that contain a Q_OBJECT macro. Similarly, when setting
++ \l {CMake AUTOMOC Documentation}{AUTOMOC} to \c ON, CMake will scan the
++ header and source files at build time and invoke \c moc accordingly.
++
++ If the class declaration is found in the file \c myclass.h, the
++ moc output should be put in a file called \c moc_myclass.cpp.
++ This file should then be compiled as usual, resulting in an
++ object file, e.g., \c moc_myclass.obj on Windows. This object
++ should then be included in the list of object files that are
++ linked together in the final building phase of the program.
++
++ \section1 Writing Make Rules for Invoking \c moc
++
++ For anything but the simplest test programs, it is recommended
++ that you automate running the \c{moc}. By adding some rules to
++ your program's makefile, \c make can take care of running moc
++ when necessary and handling the moc output.
++
++ You can use \l {Build with CMake}{CMake} or \l qmake to generate makefiles
++ that does all the necessary \c moc handling.
++
++ If you want to create your makefiles yourself, here are some tips
++ on how to include moc handling.
++
++ For Q_OBJECT class declarations in header files, here is a
++ useful makefile rule if you only use GNU make:
++
++ \snippet snippets/code/doc_src_moc.qdoc 0
++
++ If you want to write portably, you can use individual rules of
++ the following form:
++
++ \snippet snippets/code/doc_src_moc.qdoc 1
++
++ You must also remember to add \c moc_foo.cpp to your \c SOURCES
++ (substitute your favorite name) variable and \c moc_foo.o or \c
++ moc_foo.obj to your \c OBJECTS variable.
++
++ Both examples assume that \c $(DEFINES) and \c $(INCPATH) expand
++ to the define and include path options that are passed to the C++
++ compiler. These are required by \c moc to preprocess the source
++ files.
++
++ While we prefer to name our C++ source files \c .cpp, you can use
++ any other extension, such as \c .C, \c .cc, \c .CC, \c .cxx, and
++ \c .c++, if you prefer.
++
++ For Q_OBJECT class declarations in implementation (\c .cpp)
++ files, we suggest a makefile rule like this:
++
++ \snippet snippets/code/doc_src_moc.qdoc 2
++
++ This guarantees that make will run the moc before it compiles
++ \c foo.cpp. You can then put
++
++ \snippet snippets/code/doc_src_moc.cpp 3
++
++ at the end of \c foo.cpp, where all the classes declared in that
++ file are fully known.
++
++ \section1 Command-Line Options
++
++ Here are the command-line options supported by the moc:
++
++ \table
++ \header \li Option \li Description
++
++ \row
++ \li \c {-D<macro>[=<def>]}
++ \li Define macro, with optional definition.
++
++ \row
++ \li \c{-E}
++ \li Preprocess only; do not generate meta-object code.
++
++ \row
++ \li \c{-f[<file>]}
++ \li Force the generation of an \c #include statement in the
++ output. This is the default for header files whose extension
++ starts with \c H or \c h. This option is useful if you have
++ header files that do not follow the standard naming conventions.
++ The \c <file> part is optional.
++
++ \row
++ \li \c{-Fdir}
++
++ \li \macos. Add the framework directory \c{dir} to the head of
++ the list of directories to be searched for header files. These
++ directories are interleaved with those specified by -I options
++ and are scanned in a left-to-right order (see the manpage for
++ gcc). Normally, use -F /Library/Frameworks/
++
++ \row
++ \li \c{-h}
++ \li Display the usage and the list of options.
++
++ \row
++ \li \c -i
++ \li Do not generate an \c #include statement in the output.
++ This may be used to run the moc on a C++ file containing one or
++ more class declarations. You should then \c #include the meta-object
++ code in the \c .cpp file.
++
++ \row
++ \li \c {-I<dir>}
++ \li Add dir to the include path for header files.
++
++ \row
++ \li \c{-M<key=value>}
++ \li Append additional meta data to plugins. If a class
++ has Q_PLUGIN_METADATA specified, the key-value pair will be added
++ to its meta data. This will end up in the Json object that gets
++ resolved for the plugin at run time (accessible from QPluginLoader).
++ This argument is typically used for tagging static plugins with
++ information resolved by the build system.
++
++ \row
++ \li \c -nw
++ \li Do not generate any warnings. (Not recommended.)
++
++ \row
++ \li \c{-o<file>}
++ \li Write output to \c <file> rather than to standard output.
++
++ \row
++ \li \c {-p<path>}
++ \li Makes the moc prepend \c {<path>/} to the file name in the
++ generated \c #include statement.
++
++ \row
++ \li \c{-U<macro>}
++ \li Undefine macro.
++
++ \row
++ \li \c{@<file>}
++ \li Read additional command-line options from \c{<file>}.
++ Each line of the file is treated as a single option. Empty lines
++ are ignored. Note that this option is not supported within the
++ options file itself (i.e. an options file can't "include" another
++ file).
++
++ \row
++ \li \c {-v}
++ \li Display \c{moc}'s version number.
++
++ \endtable
++
++ You can explicitly tell the moc not to parse parts of a header
++ file. \c moc defines the preprocessor symbol \c Q_MOC_RUN. Any
++ code surrounded by
++
++ \snippet snippets/code/doc_src_moc.cpp 4
++
++ is skipped by the \c moc.
++
++ \section1 Diagnostics
++
++ \c moc will warn you about a number of dangerous or illegal
++ constructs in the Q_OBJECT class declarations.
++
++ If you get linkage errors in the final building phase of your
++ program, saying that \c YourClass::className() is undefined or
++ that \c YourClass lacks a vtable, something has been done wrong.
++ Most often, you have forgotten to compile or \c #include the
++ moc-generated C++ code, or (in the former case) include that
++ object file in the link command. If you use \c qmake, try
++ rerunning it to update your makefile. This should do the trick.
++
++ \section1 Build Systems
++
++ \section2 Including header moc files
++
++ qmake and CMake behave differently with regards to including header moc
++ files.
++
++ To illustrate this with an example, suppose that you have two headers with
++ corresponding source files: \c a.h, \c a.cpp, \c b.h, and \c b.cpp. Each
++ header has a Q_OBJECT macro:
++
++ \code
++ // a.h
++ class A : public QObject
++ {
++ Q_OBJECT
++
++ public:
++ // ...
++ };
++ \endcode
++
++ \code
++ // a.cpp
++ #include "a.h"
++
++ // ...
++
++ #include "moc_a.cpp"
++ \endcode
++
++ \code
++ // b.h
++ class B : public QObject
++ {
++ Q_OBJECT
++
++ public:
++ // ...
++ };
++ \endcode
++
++ \code
++ // b.cpp
++ #include "b.h"
++
++ // ...
++
++ #include "moc_b.cpp"
++ \endcode
++
++ With qmake, if you don't include the moc-generated files (\c{moc_a.cpp} and
++ \c{moc_b.cpp}), they are compiled as separate translation units. If you
++ include them, only \c a.cpp and \c b.cpp are compiled, because the
++ moc-generated code is part of those files.
++
++ With CMake, moc-generated files that are not included anywhere are
++ collected in a single generated file, \c mocs_compilation.cpp, which
++ includes all of them and is compiled as one translation unit.
++
++ We recommend including the moc-generated file at the end of the
++ corresponding source file, regardless of the build system. Qt's own
++ sources follow this practice. It has the following advantages:
++
++ \list
++ \li The moc-generated code is compiled together with the code it
++ belongs to. The headers it needs are parsed only once, instead of
++ once more in a separate translation unit.
++ \li With CMake, \c mocs_compilation.cpp grows with every header whose
++ moc-generated file is not included, and it is recompiled whenever
++ any of these headers changes. Being a single translation unit, it
++ cannot be split across build jobs and can become a bottleneck in
++ parallel builds.
++ \endlist
++
++ For more information on CMake's moc support regarding this topic, see
++ \l {Including header moc files in sources}.
++
++ \section1 Limitations
++
++ \c moc does not handle all of C++. The main problem is that class
++ templates cannot have the Q_OBJECT macro. Here is an example:
++
++ \snippet snippets/code/doc_src_moc.cpp 5
++
++ The following constructs are illegal. All of
++ them have alternatives which we think are usually better, so
++ removing these limitations is not a high priority for us.
++
++ \section2 Multiple Inheritance Requires QObject to Be First
++
++ If you are using multiple inheritance, \c moc assumes that the
++ first inherited class is a subclass of QObject. Also, be sure
++ that only the first inherited class is a QObject.
++
++ \snippet snippets/code/doc_src_moc.cpp 6
++
++ Virtual inheritance with QObject is \e not supported.
++
++ \section2 Function Pointers Cannot Be Signal or Slot Parameters
++
++ In most cases where you would consider using function pointers as
++ signal or slot parameters, we think inheritance is a better
++ alternative. Here is an example of illegal syntax:
++
++ \snippet snippets/code/doc_src_moc.cpp 7
++
++ You can work around this restriction like this:
++
++ \snippet snippets/code/doc_src_moc.cpp 8
++
++ It may sometimes be even better to replace the function pointer
++ with inheritance and virtual functions.
++
++ \section2 Enums and Typedefs Must Be Fully Qualified for Signal and Slot Parameters
++
++ When checking the signatures of its arguments, QObject::connect()
++ compares the data types literally. Thus,
++ \l{Qt::Alignment}{Alignment} and \l{Qt::Alignment} are treated as
++ two distinct types. To work around this limitation, make sure to
++ fully qualify the data types when declaring signals and slots,
++ and when establishing connections. For example:
++
++ \snippet snippets/code/doc_src_moc.cpp 9
++
++ \section2 Nested Classes Cannot Have Signals or Slots
++
++ Here's an example of the offending construct:
++
++ \snippet snippets/code/doc_src_moc.cpp 11
++
++ \section2 Signal/Slot return types cannot be references
++
++ Signals and slots can have return types, but signals or slots returning references
++ will be treated as returning void.
++
++ \section2 Only Signals and Slots May Appear in the \c signals and \c slots Sections of a Class
++
++ \c moc will complain if you try to put other constructs in the \c
++ signals or \c slots sections of a class than signals and slots.
++
++ \sa {Meta-Object System}, {Signals and Slots}, {Qt's Property System}
++ */