Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Basic question: Including headers with INCLUDEPATH doesn't work



  • By the way:
    the problem really is Q_OBJECT...

    I just wrote "Q_OBJECT" into the myQString class and look what happened: undefined reference vtable ... in myQString.cpp!

    So Q_OBJECT makes the problems why I have to add all headers to the project! How can I avoid this?


  • Lifetime Qt Champion

    when u add Q_OBJECT, please run qmake!



  • I already tried that.
    Building, running
    Building, qmake, running
    qmake, running
    qmake, building, running

    None of the above ways succeded


  • Lifetime Qt Champion

    @Binary91
    then please as last test
    Complete delete the build folder.



  • tried that, two.

    Deleted everything but my project file and the sources/headers. Didn't work :-(

    Is it possible that qmake ignores INCLUDEPATH?


  • Lifetime Qt Champion

    @Binary91
    Well anything seems possible with your setup. :)
    Q_OBJECT should not bork anything.

    Im out of ideas :)



  • Well, I'll post the whole project file, its headers and sources and maybe you can copy/paste it and try to run it with?

    If it works, then it is a setting problem. If not, something with my include logic doesn't work.

    project file:

    #-------------------------------------------------
    #
    # Project created by QtCreator 2016-11-17T15:45:17
    #
    #-------------------------------------------------
    
    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = CourseCalculator
    TEMPLATE = app
    
    INCLUDEPATH += C:/Qt/lib/headers
    
    HEADERS  += main.h
    
    SOURCES += main.cpp
               C:/Qt/lib/sources/myQString.cpp \
               C:/Qt/lib/sources/myQLineEdit.cpp \
               C:/Qt/lib/sources/myQPushButton.cpp
    
    

    main.cpp:

    // main.cpp
    
    #include "main.h"
    
    int main(int argc, char *argv[])
    {
      QApplication applicationApp(argc, argv);
      clsWindowMain windowMain;
    
      QTimer::singleShot(0, &windowMain, SLOT(slotStart()));
      int ret = applicationApp.exec();
      return ret;
    }
    
    main.h:
    

    // main.h

    #ifndef MAIN_H
    #define MAIN_H
    
    #include <QApplication>
    #include <QTimer>
    #include <QWidget>
    #include <QDialog>
    
    #endif // MAIN_H
    

    myQLineEdit.h:

    // myQLineEdit.h
    
    #ifndef MYQLINEEDIT_H
    #define MYQLINEEDIT_H
    
    #include <QDebug>
    #include <QLineEdit>
    #include <QMessageBox>
    #include <QDir>
    
    
    // forward declaration
    
    class myQLineEdit;
    
    
    // declaration
    
    class myQLineEdit : public QLineEdit
    {
      Q_OBJECT
    
      // .. properties
    
      public:
        myQLineEdit(QWidget* widgetParent = 0);
        ~myQLineEdit();
    
        // .. more methods
    };
    
    #endif
    
    

    myQLineEdit.cpp:

    // myQLineEdit.cpp
    
    #include <myQLineEdit.h> // absolute path or absolute path with whitespaces also doesn't work
    
    
    // ----- constructors -----
    
    myQLineEdit::myQLineEdit(QWidget* widgetParent) : QLineEdit(widgetParent)
    {
       // stuff
    }
    

    Is that compilable for you?


  • Lifetime Qt Champion

    @Binary91
    would be very much easier if you zipped folder and shared via dropbox or g drive as
    copy paste to real files again is very error prone and time consuming :)



  • Good idea. But my dropbox accout has no free memory left :-D

    Have to create a new account first, maybe on g drive...


  • Lifetime Qt Champion

    @Binary91
    well a zipped project is ultra small. so delete/remove something for a moment and it should have space :)

    btw: G Drive is 15 GB but the client is nowhere near as nice as dropbox.


  • Qt Champions 2019

    @Binary91 If you derive from Qt classes which are derived from QObject then you need to include the generated moc_ files.
    For example in myQLineEdit.cpp add

    #include "moc_myQLineEdit.cpp"
    


  • but from where do I get this moc file?
    If I try to include, compiler gives me an error that it can not find such file or directory

    btw:
    https://www.dropbox.com/s/whqdkcat767224t/test.zip?dl=0


  • Qt Champions 2019

    @Binary91 You should read the Qt documentation. The moc_ files are generated for you using moc tool. Take a look at the build directory.


  • Qt Champions 2019

    @Binary91 Why do you have a main.h? This is quite unusual.


  • Qt Champions 2019

    @Binary91 For QApplication you need QT += gui, else you should use QCoreApplication.



  • @jsulm , why would you include the MOC files? I "never" include the MOC files in my source because they get generated, compiled, and linked after the normal build. The only generated file I would include is the ui_NameOfForm.h file created when using the form designer. And, only in the CPP for the UI class.

    @Binary91 , I am sure it was explained that INCLUDEPATH tells qmake where to find common include files. I use it for 3rd party libraries or pre-built packages I developed for Qt (I treat them like 3rd party libraries). And, as I know you know... always run qmake after changing a PRO file.

    There is one curious item I have found about QtCreator though... if you are using static libraries (even if your dependencies are setup) and make a change to a CPP file in the library... Press build-all and it will build the library and NOT re-link the application or shared library that depends on that static library. Kind of annoying but I just get around it!



  • I know what moc files are, but they were not permanently created by QtCreator (not in my build folder).
    But can you tell me why I should have to generate them and manually include them when it works to simply add the headers to the project?
    I mean, I wanted to reduce work by using INCLUDEPATH and NOT adding all the included headers.
    Generating moc files and manually adding them is not reducing but increasing work.

    Also I do not understand why I should include them when I don't need it if I add the headers directly...


  • Qt Champions 2019

    @Binary91 Where is myudp.cpp ?


  • Qt Champions 2019

    @jsulm With some fixes I can build your project.
    pro file:

    QT       += core network
    
    QT       -= gui
    
    TARGET = test
    CONFIG   += console
    CONFIG   -= app_bundle
    
    TEMPLATE = app
    
    INCLUDES += lib/headers/myQLineEdit.h
    
    SOURCES += main.cpp \
        #myudp.cpp
    
    #HEADERS += \
    #    myudp.h
    

    main.cpp

    #include <QCoreApplication>
    
    int main(int argc, char *argv[])
    {
      QCoreApplication applicationApp(argc, argv);
      //clsWindowMain windowMain;
    
      //QTimer::singleShot(0, &windowMain, SLOT(slotStart()));
      int ret = applicationApp.exec();
      return ret;
    }
    

  • Qt Champions 2019

    @Binary91 Where I did say you have to create moc_ files manually?
    They are generated for you. And they are completely unrelated to your problem!



  • It's getting strange now :-D

    What is a myudp.cpp ?? I didn't ever used this...

    @jsulm
    But you are including the header directly now. That is exaclty what I tried to avoid...

    Why is main.h unusual? I think using headers as a bundle of #include directives for my purposes is the correct way, so in the source file, there only exists one #include directive to its corresponding header file. Not good?


  • Qt Champions 2019

    @Binary91 That is what you uploaded:

    SOURCES += main.cpp \
        myudp.cpp
    

    main.h is unusual because there is no need for it. You only need a header file if you need to include some functionality provided in one source code file in another one. Where do you want to include main.h and why (and please do not say in main.cpp, because there is no need to do it this way)?
    I will try to change your project to use INCLUDEPATH.


  • Qt Champions 2019

    @Binary91 It builds here if I do:

    QT       += core network
    
    QT       -= gui
    
    TARGET = test
    CONFIG   += console
    CONFIG   -= app_bundle
    
    TEMPLATE = app
    
    #INCLUDES += lib/headers/myQLineEdit.h
    INCLUDEPATH += lib/headers
    
    SOURCES += main.cpp
    


  • I really don't know from where this "myudp.cpp" comes. Maybe a de-zipping error. That should mean "lib/sources/myQLineEdit.cpp"

    Yeah this way its getting built on my computer as well, but there you manually added the header file to the project:
    INCLUDES += ...
    or
    HEADERS +=...

    That is what I try to avoid by using INCLUDEPATH. That was what the discussion is all about...


  • Qt Champions 2019

    @Binary91 Where did I add the header file manually?
    I commented out the old line, please take a look again:

    QT       += core network
    
    QT       -= gui
    
    TARGET = test
    CONFIG   += console
    CONFIG   -= app_bundle
    
    TEMPLATE = app
    
    #INCLUDES += lib/headers/myQLineEdit.h <-- this line is commented out
    INCLUDEPATH += lib/headers
    
    SOURCES += main.cpp
    


  • but where is the myQLineEdit.cpp ?
    You just added the main.cpp. The error occures in myQLineEdit.cpp, because it holds methods of myQLineEdit class in myQLineEdit.h that has a Q_OBJECT within...


  • Qt Champions 2019

    @Binary91 Your project is really broken:

    QT       += core network
    
    QT       += gui widgets
    
    TARGET = test
    CONFIG   += console
    CONFIG   -= app_bundle
    
    TEMPLATE = app
    
    HEADERS += lib/headers/myQLineEdit.h
    INCLUDEPATH += lib/headers
    
    SOURCES += main.cpp \
        lib/sources/myQLineEdit.cpp
    

    myQLineEdit.cpp

    #include <myQLineEdit.h> // absolute path or absolute path with whitespaces also doesn't work
    
    
    // ----- constructors -----
    
    myQLineEdit::myQLineEdit(QWidget* widgetParent) : QLineEdit(widgetParent)
    {
       // stuff
    }
    
    myQLineEdit::~myQLineEdit()
    {
    
    }
    
    #include "../build-test-Desktop-Debug/moc_myQLineEdit.cpp"
    

    Without HEADERS moc_ file is not generated and the header file is not shown in QtCreator, so you should use HEADERS.


  • Qt Champions 2019

    @jsulm said in Basic question: Including headers with INCLUDEPATH doesn't work:

    #include "../build-test-Desktop-Debug/moc_myQLineEdit.cpp"

    you can change it to:

    #include "moc_myQLineEdit.cpp"
    

    It builds now on my machine.


  • Qt Champions 2019

    @Buckwheat You need to include moc_ files for your own classes which are derived from QObject (directly or indirectly).



  • Hi jsulm,

    so you say, I need to include the headers with HEADERS in the project file. Well, then I'm asking myself what the INCLUDEPATH command is for?


  • Lifetime Qt Champion

    @Binary91 said in Basic question: Including headers with INCLUDEPATH doesn't work:

    INCLUDEPATH
    http://doc.qt.io/qt-5/qmake-variable-reference.html#includepath

    Its used to specify where to look for headers.
    So when it sees #include "YYYY" it will search for them there.

    as shown with

    INCLUDEPATH += ../../Common/CONET
    ../../Common/XML/pugixml-1.5/src/ \

    the pugixml.h is in the src and i can just use
    it like
    #include "pugixml.h"

    Without it I would have to do use full path to it.

    That is its role and it works fine here.

    You seem to expect that point to a folder with INCLUDEPATH,
    implies that all should be used ?

    Like all where already added to HEADERS ?

    There is one issue if it did that.
    For all HEADERS , it need to run moc on them so
    if you use INCLUDEPATH to point to a place with many .H files
    you be wasting tons of time running moc on those completely unrelated files.
    Hence HEADERS tells us what files to run moc on.
    Of course this could be fixed checking against which are actually seen via #include
    but it's not the way it works currently. :)



  • thank you mrjj, that was the explanation I was looking for!

    I didn't know that with HEADERS I tell the compiler which moc files should be generated!

    So all in all, I have to include those headers to my project and everything is going well.

    Thank you for your help.

    Kind regards,
    Binary



  • @jsulm Actually you don't. When the build system sees the Q_OBJECT, it will build and compile a MOC file for you. It will link into the application and be part of it. No inclusion is necessary. None at all. The only think you would ever include is a form generated header file (ie. ui_MainWindow.h) that will hold the form variables for you.

    If doubting, watch your build on any system. You will see the CPP files compile and then the moc_*.cpp files compile and then the linker will have both on it. The MOC files tie your class to the signal/slots and meta object data all under the scenes. It is quite beautifully designed.


  • Lifetime Qt Champion

    If your QObject based class is in a .cpp file then you need to include the moc file at the bottom. See the unit tests form Qt for example.


Log in to reply