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

Subdirs : How to include a file from a project to an other project?



  • Hello, I am kinda new to qt, I have to code a tetris game for my school project, I'm using template subdirs and I couldn't figure out how can i include a file from a project to an other project.

    Here is the composition of my project :
    Project tetris containing 2 projects : core and tests.

    In my tests.pro i added this : INCLUDEPATH += "../core", so I'm able to include a class from my project core to my project tests, but I can't use it.

    Here is the errors :
    scoretest.obj : error LNK2019: unresolved external symbol "public: __cdecl Score::Score(void)" (??0Score@@QEAA@XZ) referenced in function "void __cdecl ____C_A_T_C_H____T_E_S_T____4(void)" (?____C_A_T_C_H____T_E_S_T____4@@YAXXZ)
    debug\tests.exe : fatal error LNK1120: 1 unresolved externals



  • @Sun864

    HI and welcome to devnet forum

    INCLUDEPATH is only for searching include files (header files). It is a path setting.

    Did you see already this wiki on SUBDIRS template?



  • Of course I did, I already added "tests.depends = core" and "CONFIG += ordered" to my Tetris.pro but I don't know I am missing something.
    I probably missed something, the wiki is about only the main project.pro, did I missed something in Tetris.pro or tests.pro?



  • @Sun864

    Typically it is best to have already a structure as you want to use with SUBDIRS template, but you set up and test the proejcts independently. This makes it easier to locate the problem. In a next step you can combine both project and compile together.

    In your case this seems to be a library and a main program. When you can compile and link the library successfully, you are already one step further.
    The second project would be the main program which requires to link with the library of the first project.

    Are you using Qt creator as IDE?
    Which OS are you on?



  • Yes I'm using Qt creator as IDE and I'm on Windows 7.

    My project tests contains unit testing of my project core, I don't get it, I have to compile the first project when I compile the second to make it work? Sorry this is the first time I'm using SUBDIRS and trying to include a file from an other project.



  • @Sun864

    Suppose
    1 folder with a library Lib1 on c:/Source/Lib1

    Lib1.h

    #ifndef LIB1_H
    #define LIB1_H
    
    #include "lib1_global.h"
    
    class LIB1SHARED_EXPORT Lib1
    {
    
    public:
        Lib1();
    };
    #endif // LIB1_H
    

    lib1_global.h:

    #ifndef LIB1_GLOBAL_H
    #define LIB1_GLOBAL_H
    
    #include <QtCore/qglobal.h>
    
    #if defined(LIB1_LIBRARY)
    #  define LIB1SHARED_EXPORT Q_DECL_EXPORT
    #else
    #  define LIB1SHARED_EXPORT Q_DECL_IMPORT
    #endif
    
    #endif // LIB1_GLOBAL_H
    

    Lib1.cpp

    #include "Lib1.h"
    #include <QDebug>
    
    Lib1::Lib1()
    {
        qDebug() << "hello!";
    }
    

    Lib1.pro

    #-------------------------------------------------
    #
    # Project created by QtCreator 2017-04-03T20:37:42
    #
    #-------------------------------------------------
    
    QT       -= gui
    
    TARGET = Lib1
    TEMPLATE = lib
    
    # next line is added for getting the libraries off the shadow folder
    DESTDIR = $$PWD
    
    DEFINES += LIB1_LIBRARY
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += Lib1.cpp
    
    HEADERS += Lib1.h\
            lib1_global.h
    

    1 folder with the main application on c:/Source/Main1

    #include <QCoreApplication>
    
    #include "Lib1.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Lib1 tst;
    
        return 0; // a.exec();
    }
    

    and Main1.pro

    QT += core
    QT -= gui
    
    CONFIG += c++11
    
    TARGET = Main1
    CONFIG += console
    CONFIG -= app_bundle
    
    TEMPLATE = app
    
    # the next two lines are added manually
    INCLUDEPATH += ../Lib1
    LIBS += -L$$PWD/../Lib1 -lLib1
    
    SOURCES += main.cpp
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    

    1 folder with the subdirs project on c:/Source/Subdirs1
    Subdirs1.pro

    TEMPLATE = subdirs
    
    SUBDIRS = \
                MyLib1 \
                MyMain1
    
    # where to find the sub projects - give the folders
    MyLib1.subdir = ../Lib1
    MyMain1.subdir = ../Main1
    
    # what subproject depends on others
    MyMain.depends = MyLib1
    
    CONFIG += ordered
    

    If you put the files into respective folders and open each of those project files (.pro) individually in Qt creator, you shall be able to compile the library and the main application separately. When you have compiled and linked the main application, you can run it.

    Finally you can open also the subdirs project and compile, link and run all at once. That is all the principle magic behind subdirs template. For those peanuts projects it is an overkill, but when you have more complex structures it makes sense and helps to structure your different tasks.

    BTW: I have simply created the lib and main projects through Qt creator and added only minimal changes. After this I have added the subdirs project and added most of it manually.


  • Lifetime Qt Champion

    Hi,

    Are you sure about this path -L$$PWD/../Lib1 ?



  • @SGaist

    For sure not absolutely required, but it does work.

    However, this looks more consistent in Main1.pro

    # the next two lines are added manually
    INCLUDEPATH += ../Lib1
    LIBS += -L../Lib1 -lLib1
    

    Side note: The libraries of Lib1.pro have been placed in the source folder of Lib1 with:

    # next line is added for getting the libraries off the shadow folder
    DESTDIR = $$PWD
    

    Certainly I would not do for large projects. For this short demonstration it helps IMHO to focus.


  • Lifetime Qt Champion

    Sorry, I was thinking about to point the project to the actual path where the library were put after being built so rather something like -L$OUT_PWD/lib where all the sub-projects would put their libraries. So there's no need to copy anything in the sources.



  • @SGaist

    But how this be useful?
    OUT_PWD states that this is folder with the makefiles. However, it should be of the other project, shouldn't it?


  • Lifetime Qt Champion

    Since it's a subdir project, you can create a .pri file that you'll use in all libraries subprojects to put the build result in a known place in the build tree. Known folder that you can then use from your application project.


Log in to reply