[cmake-developers] Current deficiencies of automoc

Sascha Cunz sascha at cunz-rad.com
Fri Oct 21 22:35:45 EDT 2016

Hi Alan,

> On 22 Oct 2016, at 02:01, Alan W. Irwin <irwin at beluga.phys.uvic.ca> wrote:

> I don't agree with your above conclusion.  The above remarks immediately refer to
> header files and imply automoc scans them

Which it does :)

> to find the ones that contain the Q_OBJECT macro and

and/or Q_GADGET.

> certainly does not imply the user must list the files to be scanned directly

Right. And it’s not required most of the time.
But automoc must know where to look for. It can only do that if something tells it where to look - If your header files are in the same directory as the source files, they’re getting added and scanned automatically (Not related to automoc, actually). See the minimum example below.

If, like in your example, the files are in different directories, you have to add them to add_executable / add_library in order to let automoc know that it shall scan them.

> as fullpaths in the add_executable (or add_library) command.

The full path requirement here is a false perception. It will certainly do no harm to be explicit with the parameters to add_executable/add_library, but the default is to search relative to ${CMAKE_CURRENT_SOURCE_DIR}.

And as mentioned by others in the thread, it’s a good idea to explicitly list your header files. As this will improve how certain IDEs show your project.

The above _is_ actually the default behaviour that suites 95% of the cases where moc needs to be run. For the other cases, where Q_OBJECT / Q_GADGET is used inside a .cpp file, there is the option to #include a file following the pattern “moc_%s.cpp” where %s is the name of the containing C++ source file without extension. 

> And the last sentence implies that if the so-called #include method is not used, then
> automoc will figure everything out for itself, i.e., the fullpath method allowing the
> user to specify which headers are scanned by moc is not documented here at all.

From cmake-qt[7]:

	The AUTOMOC target property controls whether cmake(1)
		inspects the C++ files in the target
	to determine if they require moc to be run.

I clearly states that it will scan the files added to the target.

However, I see that the take away from the thread should probably be that the wording in the documentation could be improved. To be fair, it is in general very hard for someone who knows a tool and it’s complete history to write documentation that someone who doesn’t have that prior knowledge is able to understand. So, improving things here usually relies on input like yours to figure out what actually has to be improved.
I could imagine that in this case, the term “C++ files” didn’t trigger an association to header files.


P.S.: Since both Qt4 and Qt5 integrations of Qt nowadays use generator expressions, in my experience it’s close to impossible to accurately mimic automoc behaviour inside CMakeLists.txt. This is though required in one specific scenario, but I don’t think this can be fixed unless automoc would be rewritten from scratch (If target T has a custom rule that creates a header file, which turns out to be run through moc - automoc, which is a separate target that T depends on, can impossibly scan the file that [through target-dependency] will be generated _after_ the automoc target is built).

Minimal working example:

$ tail -n50 CMakeLists.txt t.cpp t.hpp
==> CMakeLists.txt <==
cmake_minimum_required(VERSION 3.6)
add_executable(a t.cpp)
target_link_libraries(a Qt5::Core)

==> t.cpp <==
#include "t.hpp"
int main(int,char**)
{ X x; return 0; }

==> t.hpp <==
#include <QObject>
struct X: public QObject{
	X() = default;

More information about the cmake-developers mailing list