Uploaded image for project: 'Qbs ("Cubes")'
  1. Qbs ("Cubes")
  2. QBS-1410

qbs fails to run moc when class is declared through a macro from another file



    • Bug
    • Resolution: Done
    • P4: Low
    • 1.13.0
    • 1.12.1
    • Libraries: Qt
    • None
    • gcc 7.3, Qt-5.11.2, Qbs 1.12.1 (Linux)
    • All
    • 5c84373d8d60a8b13df1fcdcd77480736952c095 (qbs/qbs/master)


      In my project I need to create QObject derived classes (with Q_OBJECT and signals) using a macro. The macro resides in a separate file. Here is a simplified example:

      The macro is declared in the file CreateQtClass.h:


      #ifndef __CREATEQTCLASS_H__
      #define __CREATEQTCLASS_H__
      #define CREATE_QT_CLASS( ClassName ) \
      class ClassName : public QObject \
      { \
       Q_OBJECT \
       signals: \
       Q_SIGNAL void mySignal( void ); \
      #endif //__CREATEQTCLASS_H__

      I use the macro to create my class in the file MyQtClass.h


      #ifndef __MYQTCLASS_H__
      #define __MYQTCLASS_H__
      #include <QObject>
      #include "CreateQtClass.h"
      CREATE_QT_CLASS( MyQtClass );
      #endif //__MYQTCLASS_H__

       In my .qbs file, I add MyQtClass.h to the files property, like this:


      import qbs
      QtApplication {
       name: "HelloWorld-Qt"
       files: [ "main.cpp", "MyQtClass.h" ]

      The file main.cpp:


      #include <QDebug>
      #include "MyQtClass.h"
      static void mySlot( void )
       qDebug() << "Hello slot";
      int main( void )
       MyQtClass c;
       QObject::connect( &c, &MyQtClass::mySignal, &mySlot );
       emit c.mySignal();
       return 0;

      When running

      qbs build

      qbs doesn't run 'moc' on MyQtClass.h. It looks like it doesn't do the scanning correctly, and doesn't detect the Q_OBJECT inside the macro.

       I have created a simple Makefile to shows that when manually forcing moc to run on MyQtClass.h, everything works well. This is the Makefile:


      CXX = /usr/bin/g++
      QT_VERSION = 5.11.2
      QT_PATH = /home/user/programs/Qt$(QT_VERSION)/$(QT_VERSION)/gcc_64
      MOC = $(QT_PATH)/bin/moc
      INCLUDES = \
       -I$(QT_PATH)/include \
       -I$(QT_PATH)/include/QtCore \
       -I$(QT_PATH)/mkspecs/linux-g++ \
      LINK_FLAGS = \
       -Wl,-m,elf_x86_64,-rpath,$(QT_PATH)/lib \
       -L$(QT_PATH)/lib \
       -m64 $(QT_PATH)/lib/libQt5Core.so.$(QT_VERSION) \
      C_FLAGS = \
       -g \
       -O0 \
       -Wall \
       -Wextra \
       -m64 \
       -pipe \
       -fexceptions \
       -fvisibility=default \
       -fPIC \
       -DQT_CORE_LIB \
       $(INCLUDES) \
      SOURCES = main.cpp
      OBJS = $(SOURCES:%.cpp=%.cpp.o)
      MOC_OBJS = $(HEADERS_THAT_NEED_MOC:%.h=moc_%.cpp.o)
      all: HelloWorld-Qt
      HelloWorld-Qt: $(OBJS) $(MOC_OBJS)
       $(CXX) $^ $(LINK_FLAGS) -o $@
      %.cpp.o : %.cpp
       $(CXX) $(C_FLAGS) -c $^ -o $@
      moc_%.cpp: %.h
       $(MOC) -DQT_CORE_LIB $(INCLUDES) $^ -o $@
       rm -f *.cpp.o HelloWorld-Qt moc_*.cpp

       I think that the problem is that qbs and moc do not scan the files in the same manner. Qbs tries to detect whether the file MyQtClass.h needs to be moc'ed but fails where moc itself succeeds.

      The lack of consistency between the two tools (qbs, moc) can lead to situations where files are not detected correctly.

      For this reason I think that we need some kind of way to manually tell Qbs that a file (MyQtClass.h, in my case) needs to be moc'ed.

      What I suggest is that we add new a fileTag such as "force_moc" which we can attached to files such as MyQtClass.h and force qbs to run moc on them.


      Attached all the files to reproduce the problem + the Makefile


        No reviews matched the request. Check your Options in the drop-down menu of this sections header.



            kandeler Christian Kandeler
            john_smith a a
            0 Vote for this issue
            1 Start watching this issue



              Gerrit Reviews

                There are no open Gerrit changes