Issue #2 new

AutoMoc of Header Files

Rick Dunlap
created an issue

I have spent about a day trying to coerce Qt5 tool into 'moc-ing' header files which do not have an associated 'cpp' file. I have tried explicit 'moc-ing' as well, to no avail.

Here is the header file in question:

#include <QObject>
#include <QtQml>

class JCFLineBadgeTypes {
    Q_OBJECT
    Q_ENUMS(LineBadgeTypes)

public:
    enum LineBadgeTypes {
        BadgeTypeVoiceMail = 0,
        BadgeTypeMissedCall 
    };

    static void declareQML() {
        qmlRegisterUncreatableType<JCFLineBadgeTypes>("LineBadgeTypes", 1, 0, "LineBadgeTypes", "Enums cannot be instantiated!");
    }
};

When I build from QtCreator, the above file is 'moc-ed' and a 'cpp' file is created. I have tried the following in my Sconscript:

envLocal.XMoc5(headerFile.get_path())

As well as:

envLocal.ExplicitMoc5(os.path.join(thedir, 'moc_'+base+'.cpp'), headerFile.get_path())

I get no errors, but I also get no 'moc' files.

Note that the above class initially used 'Q_GADGET' instead of 'Q_OBJECT', I thought that this was the problem as the tool is only looking for 'Q_OBJECT'.But changing from Q_GADGET to Q_OBJECT had no effect.

Note that the auto-moc is working for 'cpp' files, just not header files.

The bug/enhancement request is support for 'moc-ing' header files in absence of 'cpp' files. Also, auto-moc should work with Q_GADGET as well as Q_OBJECT.

Comments (8)

  1. dirkbaechle repo owner

    Hi Rick,

    your class doesn't inherit from QObject, so when I call the Qt4 moc on it via command-line:

    moc test.h
    

    , I get:

    test.h:5: Error: Class contains Q_OBJECT macro but does not inherit from QObject
    

    . Please try this with your moc-qt5 and make sure that the MOC executable creates some output at all. If this wasn't the error, we have to search elsewhere...but the ExplicitMoc builder is really dumb. It simply calls the MOC with the two arguments, so if it works in the shell, the builder should work, too.

    Best regards,

    Dirk

  2. dirkbaechle repo owner

    Okay, got it now...although I've been working with Qt since v2.x, this is actually the first time I encountered Q_GADGET. Good to know this!

    I saved your header file as "test.h", and could successfully run it through Qt4 with the following SConstruct:

    env = Environment(tools=['default','qt4'])
    env.ExplicitMoc4('moc_tst.cpp','test.h')
    

    Can you try this simple setup on your side?

    Regards,

    Dirk

  3. Rick Dunlap reporter

    I figured out what the problem was. I was a cascade of two errors. First, I left automoc enabled by accident and I ran into duplicate target file definitions. I "temporarily" removed the explicit-mod target from the target for testing and forgot to add it back.

    I resolved everything by setting AUTO_MOC to '0' and by manually adding all moc files to the target. Now it all works.

    Thanks for your help! And thanks for creating this tool. It is very helpful.

  4. dirkbaechle repo owner

    I'm glad to hear that it's working for you now.

    I'll leave this issue open and ponder over the idea of automoc'ing headers a bit. The problem with this approach will be that you then have to specify the headers as sources to your Program/Library too. Else, the Qt tool can't find the headers it should check for whether they get moc'ed or not. This is usually done by searching for a header existing with the same name stem as a source file.

    Thanks for the basic idea though.

    Best regards,

    Dirk

  5. Rick Dunlap reporter

    Hmm…

    How about a simpler approach involving only explicit-moc? For example, detect a that an explicit header (passed by ExplicitMoc5 for example) needs to be moc-ed due to the presence of the Q_OBJECT (or Q_GADGET) macro? Ignore files passed that do not need to be moc-ed.

    As it is now, when moc is run on a file that is not contain Q_OBJECT, an empty moc_*.cpp file is created. This doesn't seem to cause any problems, but it is a bit messy.

    Ciao,

    Rick

  6. Bertwim van Beest

    I have a related issue, and unfortunately I have found no way yet to overcome it.

    In my case, header files (containing Q_OBJECT) reside in a directory that is different from where the corresponding implementation files reside. This situation is typical for the source code of a library when you don't want to expose all header files, but only the ones that matter for the consumers of the library.

    I tried things like putting env.Moc5( "../include/*.h" ) in the SConscript file, but I just cannot make it work. Bottomline is the generated moc_binaries never are linked together with the end target, I alwas get linker errors.

    Are there any suggestions? Kind Regards,

  7. dirkbaechle repo owner

    In your situation you'll have to call the ExplicitMoc method for each single *.h header file, I'm afraid. I have setup a simple example with the Qt4 Tool, how can I send you the archive (*.tgz)? You might want to come over to our SCons User mailing list with this question....there I can attach arbitrary files to a reply.

  8. Log in to comment