Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. fail to use Q_OBJECT Macro in CMake Project

fail to use Q_OBJECT Macro in CMake Project

Scheduled Pinned Locked Moved Unsolved General and Desktop
moccmakeqobject
14 Posts 4 Posters 9.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sewing
    wrote on last edited by
    #1

    I am having trouble with the meta Object Compiler of Qt in my CMake Project. A shared lib I am building contains the following code and employs the pimpl idiom. After invoking CMake and upon compilation I get

    AUTOGEN: error: ~/tools/Project/gui/src/mainWindow.cpp: The file contains a Q_OBJECT macro, but does not include "mainWindow.moc" ! gui/CMakeFiles/gui_automoc.dir/build.make:57: recipe for target 'gui/CMakeFiles/gui_automoc' failed make[2]: *** [gui/CMakeFiles/gui_automoc] Error 1 CMakeFiles/Makefile2:234: recipe for target 'gui/CMakeFiles/gui_automoc.dir/all' failed
    

    I dont get what I am doing wrong or whats the correct way to incorporate src files with the Q_OBJECT Macro in my project.

    Please help =/

    gui/src/mainWindow.hpp

    
    #include <QMainWindow>
    #include <string>
    
    
    class MainWindow : public QMainWindow {
      class MainWindowImpl;
    
     public:
      MainWindow(QWidget* parent = nullptr);
    
     private:
      MainWindowImpl* pimpl_;
    };
    gui/include/gui/mainWindow.cpp
    
    #include "gui/mainWindow.hpp"
    
    class MainWindow::MainWindowImpl : public QWidget{
     Q_OBJECT
      public:
       explicit MainWindowImpl(MainWindow *parent);
    
      private:
       MainWindow &parent_;
    };
    
    MainWindow::MainWindowImpl::MainWindowImpl(MainWindow *parent)
        : QWidget{parent}, parent_(*parent) {}
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent} {
        pimpl_ = new MainWindowImpl{this};
        setCentralWidget(pimpl_);
    }
    

    I compile the library like so:

    cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
    project(gui)
    
    add_library(${PROJECT_NAME}
      SHARED
       src/mainWindow.cpp
    )
    add_library(gui::gui ALIAS ${PROJECT_NAME})
    
    target_include_directories(${PROJECT_NAME} 
      PUBLIC 
       ${PROJECT_SOURCE_DIR}/include
    )
    
    set_target_properties(${PROJECT_NAME} PROPERTIES AUTOMOC TRUE)
    
    target_link_libraries(${PROJECT_NAME}
      PUBLIC
       Qt5::Widgets
       Qt5::Core
       Qt5::Xml
       Qt5::OpenGL
       Qt5::Gui
    )
    
    install(TARGETS ${PROJECT_NAME} DESTINATION lib)
    

    Now I want to link this lib against my executable

    apps/main.cpp
    
    #include <QApplication>
    #include "gui/mainWindow.hpp"
    
    int main(int argc, char *argv[]) {
    
    QApplication app{argc, argv};
    
    MainWindow gui{};
    gui.show();
    
    return app.exec();
    }
    

    with the following CMakelists.txt where I link against the gui lib

    cmake_minimum_required (VERSION 3.5.1 FATAL_ERROR)
    project (app)
    
    add_executable(${PROJECT_NAME}
      main.cpp
    )
    
    target_include_directories(${PROJECT_NAME}
        PUBLIC ${PROJECT_BINARY_DIR}
    )
    
    target_link_libraries(${PROJECT_NAME}
      PRIVATE
       gui::gui
       Qt5::Widgets
       Qt5::Core
       Qt5::Xml
       Qt5::OpenGL
       Qt5::Gui
     )
    
     install(TARGETS ${PROJECT_NAME}
             DESTINATION bin)
    

    my top-level CMakeLists of the project looks like the following

    cmake_minimum_required (VERSION 3.5.1 FATAL_ERROR)
    project(project)
    
    set(CMAKE_INSTALL_DIR ${PROJECT_SOURCE_DIR}/obj)
    set(CMAKE_INSTALL_PREFIX  ${CMAKE_INSTALL_DIR})
    # add our local path to the runtime path
    SET(CMAKE_INSTALL_RPATH "$ORIGIN:${CMAKE_INSTALL_PREFIX}/lib")
    # also add the link paths to the runtime paths
    SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
    
    find_package(Qt5 COMPONENTS Core Widgets Xml OpenGL Gui REQUIRED)
    
    ## --> Build libraries and applications  <--
    add_subdirectory(gui)
    add_subdirectory(apps)
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      Sewing
      wrote on last edited by
      #2

      Anyone? I am losing my mind over here -.-

      ? 1 Reply Last reply
      0
      • S Sewing

        Anyone? I am losing my mind over here -.-

        ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        @Sewing said in fail to use Q_OBJECT Macro in CMake Project:

        Anyone?

        It's only 2 hours since your initial post. Please show a little more patience, like 24 hours. It's always nighttime for half of the community. And it's friday.

        1 Reply Last reply
        5
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          Did you already took a look at the CMake Manual from Qt's documentation ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          VRoninV 1 Reply Last reply
          0
          • S Offline
            S Offline
            Sewing
            wrote on last edited by
            #5

            I did, but without being able to infer any conclusive hints from the article towards a solution for my problem

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #6

              The problem is not CMake:

              @Sewing said in fail to use Q_OBJECT Macro in CMake Project:

              mainWindow.cpp: The file contains a Q_OBJECT macro

              from http://doc.qt.io/qt-5/moc.html

              The moc tool reads a C++ header file.

              Did you declare a class with Q_OBJECT in a .cpp file? if so either yo do as the compiler tells you and #include "mainWindow.moc" (this file name might change depending on how moc gets invoked) at the end of the file or, as I would recommend, move it into a header

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              4
              • S Offline
                S Offline
                Sewing
                wrote on last edited by
                #7

                Mh difficult since I employ the pimpl idiom in which the nested implementation class in defined entirely within the source file

                VRoninV 1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Then move the private declaration part in its own header that you only include in the implementation part.

                  Note that your MainWindow implementation looks a bit convoluted, you might be over-engineering some things.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  2
                  • S Offline
                    S Offline
                    Sewing
                    wrote on last edited by
                    #9

                    thank you for the help.

                    you mean cuz of using pimpl? this is just a minimal example and my intention was, to keep the public interface of mainwindow.cpp quite clean and readable

                    1 Reply Last reply
                    0
                    • S Sewing

                      Mh difficult since I employ the pimpl idiom in which the nested implementation class in defined entirely within the source file

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #10

                      @Sewing said in fail to use Q_OBJECT Macro in CMake Project:

                      pimpl idiom in which the nested implementation class in defined entirely within the source file

                      You can move it into a header file, Qt does it all the time, they use _p.h suffix to mark private headers. For example: QDateTimePrivate

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      2
                      • S Offline
                        S Offline
                        Sewing
                        wrote on last edited by
                        #11

                        so if I understood correctly, the reason of having to do this is that the Q_OBJECT Macro has to be defined in the header file instead of the source file?

                        and after doing so, is the line

                        set_target_properties(${PROJECT_NAME} PROPERTIES AUTOMOC TRUE)
                        

                        sufficient for invoking the MOC in my CMakeLists file?

                        1 Reply Last reply
                        0
                        • SGaistS SGaist

                          Hi,

                          Did you already took a look at the CMake Manual from Qt's documentation ?

                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by
                          #12

                          @SGaist said in fail to use Q_OBJECT Macro in CMake Project:

                          Did you already took a look at the CMake Manual from Qt's documentation ?

                          @Sewing said in fail to use Q_OBJECT Macro in CMake Project:

                          I did

                          from http://doc.qt.io/qt-5/cmake-manual.html:

                          # Instruct CMake to run moc automatically when needed.
                          set(CMAKE_AUTOMOC ON)
                          

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            Sewing
                            wrote on last edited by
                            #13

                            I read that, just thought variables in CMake are old-style while target_properties are the modern way to handle things

                            VRoninV 1 Reply Last reply
                            0
                            • S Sewing

                              I read that, just thought variables in CMake are old-style while target_properties are the modern way to handle things

                              VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by
                              #14

                              I heard opposing arguments to that when it comes to moc/rcc/uic. Personally, I use the set(CMAKE_AUTOMOC ON) way

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved