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 -
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? -
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.
-
Suppose
1 folder with a library Lib1 on c:/Source/Lib1Lib1.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!"; }
#------------------------------------------------- # # 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.proTEMPLATE = 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.
-
Hi,
Are you sure about this path
-L$$PWD/../Lib1
? -
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.
-
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. -
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.