SubDir-Project Problems!
-
Hello QT-Community,
I have problems running a SubDir Project which includes two LIB-Projects (one of them is using an external library file to control a camera) and a Widget Application. The Widget Application uses both libraries, which are build first.
The problem now is, when I include the Header File of the library which includes the external library, and when I run the program, it seems to be working. But as soon as I create an object (which is using the external camera library) or I use functions which are defined in the external lib, I got an error "No such file or Directory" for the header Files of the external LIB! But the path is right, and the file is definitely the right one!
I included the LIBS, DEPENDPATH as well as the INCLUDEPATH to all external Libraries in the LIB-Projects and I also did that for the Widget Application, where I additionally include the PATH to the internal LIB-Projects.
Here is a Sample-project
SubDir-Project File:
TEMPLATE = subdirs SUBDIRS += \ Auto \ Fahrzeug \ GaragenApp Auto.depends = Fahrzeug GaragenApp.depends = Auto
Fahrzeug-LIB: --> is using an external Camera-LIB (dll)
creating this project works without any failures! Also when using the functionalities of the external library.QT -= gui TEMPLATE = lib DEFINES += FAHRZEUG_LIBRARY CONFIG += c++11 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ fahrzeug.cpp HEADERS += \ Fahrzeug_global.h \ fahrzeug.h # Default rules for deployment. unix { target.path = /usr/lib } !isEmpty(target.path): INSTALLS += target # External Camera-Library win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../libs/x64/ -lcamera2 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../libs/x64/ -lcamera2 INCLUDEPATH + = $$PWD/../include #Position of the Camera2 Header File INCLUDEPATH += $$PWD/../libs/x64 DEPENDPATH += $$PWD/../libs/x64
Auto - LIB (Project 2): --> is using Fahrzeug-Lib (Project 1)
I got an error when creating the LIB --> in Fahrzeug.h --> Camera2.h "no such file or directory"QT -= gui TEMPLATE = lib DEFINES += AUTO_LIBRARY CONFIG += c++11 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ auto.cpp HEADERS += \ Auto_global.h \ auto.h # Default rules for deployment. unix { target.path = /usr/lib } !isEmpty(target.path): INSTALLS += target #Path toFahrzeug Lib win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../Fahrzeug/release/ -lFahrzeug else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../Fahrzeug/debug/ -lFahrzeug INCLUDEPATH += $$PWD/../Fahrzeug DEPENDPATH += $$PWD/../Fahrzeug
Widget Application: --> is using Auto LIB
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ mainwindow.cpp HEADERS += \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../Auto/release/ -lAuto else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../Auto/debug/ -lAuto INCLUDEPATH += $$PWD/../Auto DEPENDPATH += $$PWD/../Auto
So what is going wrong? Where is my mistake and how can I easily set up such projects without getting in trouble with dependencies.
-
@Gogonfa79 said in SubDir-Project Problems!:
"No such file or Directory"
What file or directory? Can you show whole error message?
-
The hole error message in QTCreator is:
C:\xxx\SubDirTest\Fahrzeug\fahrzeug.h:6: Error: Camera2.h: No such file or directory
In file included from auto.h:5,
from auto.cpp:1:
..\Fahrzeug/fahrzeug.h:6:10: fatal error: Camera2.h: No such file or directory
#include "Camera2.h"
^~~~~~~~~~~~~~The crazy thing is, building the Fahrzeug-Lib alone, by right click on the project folder....it works, without any problems! Only if I create the whole SubDir-Projects, it crashes!
-
@Gogonfa79 It would be good if you would use real project names instead of things like "LIB-Project 1" - it makes it hard to understand what is using what.
I think the problem is that fahrzeug.h includes Camera2.h and fahrzeug.h is included in another project which does not define the dependency on that lib containing Camera2.h. Either do not include Camera2.h in fahrzeug.h (use forward declarations) or add dependency to the other project which includes fahrzeug.h. This other project should not know anything about Camera2.h from architectural point of view. -
@jsulm, thanks for your fast answer! That helped me :-) and sorry for my LIB-Description, I changed it into real names ...
If I set the dependencies for Camera2.h and Camera2.lib/dll in the Project-File of LIB-Project Auto, then it works. But as you mentioned, "Auto" should not know camera2.h....it only should know Fahrzeug!
But how can I make a forward declaration for "structs" ? In Camera2.h, there are some C-style structs which are defined with a "typedef". How can I make forward declarations for such types?Example:
Camera.h defines
typedef struct _CAMERA_INFO { char Name[64]; //the name of the camera, you can display this to the UI int CameraID; //this is used to control everything of the camera in other functions. long MaxHeight; //the max height of the camera long MaxWidth; //the max width of the camera double PixelSize; //the pixel size of the camera ..... }CAMERA_INFO;
I need a variable of that struct in my class Fahrzeug.
#include "Fahrzeug_global.h" #include <QtCore> //#include "Camera2.h" typedef struct _CAMERA_INFO CAMERA_INFO; class FAHRZEUG_EXPORT Fahrzeug { public: Fahrzeug(); Fahrzeug(const QString &name); void fahren(); void setName(const QString &name); const QString &getName(); private: QString m_name; CAMERA_INFO m_info; };
If I do a forward declaration like this (I only use now the camera2.h in my cpp-file)
typedef struct _CAMERA_INFO CAMERA_INFO;
which should be the same like
struct _CAMERA_INFO typedef _CAMERA_INFO CAMERA_INFO
I get an error "C:\xxx\SubDirTest\Fahrzeug\fahrzeug.h:22: Error: field has incomplete type 'CAMERA_INFO' (aka '_CAMERA_INFO')"
-
@Gogonfa79 Forward declarations only work for pointers because for pointers compiler does not need the whole type information. That means you have two possibilities:
- Use pointers (CAMERA_INFO *m_info;)
- Use pimpl approach, see https://en.cppreference.com/w/cpp/language/pimpl