Basic question: Including headers with INCLUDEPATH doesn't work



  • Hello together,

    I'm working with QtCreator and for all my previous projects, I manually included libraries (headers & sources) by adding them these files to the project.

    Well, I thought there should be an easier solution for that, because when I use pre-installed headers like QWidget.h or QApplication.h, I do not have to add these files to the project.

    So I set an INCLUDEPATH to my project config file:

    INCLUDEPATH += C:/Qt/projects/lib/headers \
                                       C./Qt/projects/lib/sources
    

    and deleted the file attachments in the project.

    By using INCLUDEPATH, QtCreator automatically autofills the name while I type it in my #include directive, BUT when I try to build/run the project, I get the following errors:
    'undefined reference to vtable for "xxx"'
    'undefined reference to vtable for "xxx"'
    ...

    When I manually add the header files and the source files via project -> right mouse click --> add existing files, everything works fine again.

    I think there should be a way to solve this without adding all those libraries manually to the project, because I also don't have to do this with the standard headers/sources from Qt...

    Can someone help me with that?

    Thank you in anticipation!
    Binary


  • Qt Champions 2016

    Hi
    'undefined reference to vtable for "xxx"'
    often comes from lack of Q_OBJECT or not running qmake after adding it.
    Are u sure its related to INCLUDEPATH ?
    Remember to run qmake when changing .pro file

    also , you show
    C./Qt/projects/lib/sources
    The DOT there is that typo and its : as it should ?

    Also that seems to point to the CPP folder.

    You only point INCLUDEPATH to .h files
    You must still include the CPP files in the actual project OR
    use the LIBS+= to point to any DLL/SO/LIB file produced.

    as explained here
    http://doc.qt.io/qtcreator/creator-project-qmake-libraries.html



  • Hi and thank you for your post.

    Yes, it should be ":" instead, that was not the problem.

    You say, I still have to include the source files (cpp).

    Two questions to that:

    1. Why do I not have to include QWidget.cpp, QApplication.cpp and so on when including such standard headers?

    2. Well, I did include the source files, set INCLUDEPATH to the directory where my header files are located, included them via #include directive in the source files (as I would do with a standard header file), built the project again and still get those errors.

    When I follow thoses errors in QtCreator, I see that they all point to the corresponding source file, like for example:
    project file:

    INCLUDEPATH += C:/Qt/lib/headers
    
    SOURCES += main.cpp \
    libA.cpp \
    libB.cpp
    
    HEADERS += main.h
    

    main.h:

    #include <libA.h>
    #include <libB.h>
    

    libA.h

    class test
    {
      test();
      ~test();
    };
    

    libA.cpp

    #include <libA.h>
    
    test::test() // <-- error here
    {
    }
    
    test::~test()  // <-- error here
    {
    }
    

    As you can see, the problem is that including the header (path should be known because I set it with INCLUDEPATH) into its corresponding source file (which I manually included in my project file).

    Can you imagine what's wrong with that?


  • Qt Champions 2016

    Hi

    • Why do I not have to include QWidget.cpp, QApplication.cpp and so on when including such standard headers?

    You should not have to include any standard Qt cpp files. the .H is enough.
    but if you write .pro file BY HAND make sure u include
    TEMPLATE = app
    and stuff like
    QT += core gui
    Else it wont link Qt to it!!

    --

    #include <libA.h>

    test::test() // <-- error here
    {
    }

    --

    Is the file
    libA.cpp IN THE SAME FOLDER as main.cpp ?



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

    You should not have to include any standard Qt cpp files. the .H is enough.

    Yeah but why do I have to with my own headers? Is there a list of pre-defined standard headers and their corresponding sources so compiler/linker knows that automatically? If yes, couldn't that list be extended by own headers/sources?

    but if you write .pro file BY HAND make sure u include
    TEMPLATE = app
    and stuff like
    QT += core gui
    Else it wont link Qt to it!!

    I do not create the whole project file by myself, QtCreator does that so all that stuff is included.

    Is the file
    libA.cpp IN THE SAME FOLDER as main.cpp ?

    Nope, should it? I thought that exactly this could be avoided by setting an INCLUDEPATH, isn't it? I thought that after setting this path, the compiler/linker knows where to search for those headers, otherwise this INCLUDEPATH doesn't have any sense or am I missing something?


  • Moderators

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

    error here

    What is the error?
    If it is something like "multiple definition" or "redefinition", then your header file probably does not contain "include guard", see here: https://en.wikipedia.org/wiki/Include_guard


  • Moderators

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

    Yeah but why do I have to with my own headers?

    Because those are yours and you have to care about them. How should the build system know?
    You don't have to include any Qt cpp files simply because you link your application against already build Qt libraries.
    If you add QT+= gui you tell qmake to link your application against QT GUI libraries.



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

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

    Yeah but why do I have to with my own headers?

    Because those are yours and you have to care about them. How should the build system know?
    You don't have to include any Qt cpp files simply because you link your application against already build Qt libraries.
    If you add QT+= gui you tell qmake to link your application against QT GUI libraries.

    Ah that makes sense! So "gui" or "core" are libs that include the source code of the headers that I include? That sounds logically!

    But I still do not know why my source files should be in the same directory as my headers when I use relative paths, because I set an INCLUDEPATH so compiler/linker should know where to search for it or am I wrong?


  • Qt Champions 2016

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

    Nope, should it?

    Well it dont matter where it is, BUT you say it is in same folder!
    So it cant find them and hence it dont like your test::test() as it never saw the .cpp file.

    also INCLUDEPATH is for .H files and NOT .cpp files!

    SOURCE is for .cpp files and iy MUST be correct path

    like where where my xml lib is somewhere else
    SOURCES += main.cpp
    Configuration.cpp
    Forms/AbstractForm.cpp \ <<<--------------- in a sub folder called Forms
    Forms/ConfigurationForm.cpp
    Forms/DefaultFormFooter.cpp \
    ../../Common/XML/pugixml-1.5/src/pugixml.cpp \

    Look at the pugixml.cpp, here i tell it to go back 2 folders and into Common

    So when you say

    SOURCES += main.cpp \ CORRECT
    libA.cpp \ WRONG. AS ITS NOT THERE
    libB.cpp Also wrong ?



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

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

    Nope, should it?

    Well it dont matter where it is, BUT you say it is in same folder!
    So it cant find them and hence it dont like your test::test() as it never saw the .cpp file.

    also INCLUDEPATH is for .H files and NOT .cpp files!

    SOURCE is for .cpp files and iy MUST be correct path

    like where where my xml lib is somewhere else
    SOURCES += main.cpp
    Configuration.cpp
    Forms/AbstractForm.cpp
    Forms/ConfigurationForm.cpp
    Forms/DefaultFormFooter.cpp \
    ../../Common/XML/pugixml-1.5/src/pugixml.cpp \

    Look at the pugixml.cpp, here i tell it to go back 2 folders and into Common

    So when you say

    SOURCES += main.cpp \ CORRECT
    libA.cpp \ WRONG. AS ITS NOT THERE
    libB.cpp Also wrong ?

    Yep I know that know and already fixed this. But I don't know why I have to set the full path of the header files after setting INCLUDEPATH?!

    That is how my project file looks like now:

    INCLUDEPATH += C:/Qt/lib/headers
    
    SOURCES += main.cpp \
    C:/Qt/lib/sources/libA.cpp \
    C:/Qt/lib/sources/libB.cpp
    
    HEADERS += main.h
    

    It still throws these errors...
    When I include those headers manually like I did with the sources, everything works fine. BUT I thought that I could avoid this with INCLUDEPATH...


  • Qt Champions 2016

    Well normally you do not need to do so...

    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"



  • @mrjj
    What could cause that problems then? Do I have to change some build settings in QtCreator?

    I mean, there is no error in the code, because after manually adding those headers to the project , like:

    HEADERS += C:/Qt/lib/headers/libA.h
    

    works without problems.
    BUT something like this:

    HEADERS += libA.h
    

    also doesn't work!

    I don't know what could be wrong. INCLUDEPATH does have an effect to QtCreator, because when I try to include one of my own headers, it searches and autofills the name of the header file. So QtCreator searches for those files in the INCLUDEPATH I set, but it can't combine them when trying to build the project...


  • Qt Champions 2016

    No, it works that way. pr default. Nothing I have seen in Creator adjust that.
    Only thing that can go wrong is path is invalid ( on windows, spaces in path can be issue)

    HEADERS += libA.h

    Will work if the libA.h is in the same folder as the .pro file
    Else its FALSE and will not work.



  • @mrjj
    I found out that the problem only appears to a few header files!

    I include 3 headers, each declaring a subclass of a standard Qt class:

    INCLUDEPATH += C:/Qt/lib/headers
    
    HEADERS += main.h
    
    SOURCES += main.cpp \
    myQLineEdit.cpp \
    myQPushButton.cpp \
    myQString.cpp
    

    The errors appear to the functions defined in the source files myQLineEdit.cpp and myQPushButton.cpp, but NOT in myQString.cpp!

    I think I got the problem!! In myQLineEdit and myQPushButton class, I do have a Q_OBJECT. Can this cause the problems??


  • Qt Champions 2016

    Q_OBJECT is used by a tool called moc.exe to help make signals and slot possible
    It should not to anything with regards to include files. :)
    As far as I have ever seen.



  • that is really annoying..
    Why do those undefind reference errors appear to some of my source files but not to all of them?
    Don't know where to search for an answer now



  • 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?


  • Qt Champions 2016

    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


  • Qt Champions 2016

    @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?


  • Qt Champions 2016

    @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?


  • Qt Champions 2016

    @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...


  • Qt Champions 2016

    @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.


  • Moderators

    @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


  • Moderators

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


  • Moderators

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


  • Moderators

    @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...


  • Moderators

    @Binary91 Where is myudp.cpp ?


  • Moderators

    @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;
    }
    

  • Moderators

    @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?


  • Moderators

    @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.


  • Moderators

    @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...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.