SUB_DIRS actual implemetation of shared library
-
After making another post I realized I have never completed installing and actually using shared library in my main project.
I went back and buidl a sample SUB_DIRS project and added a shared library - source and it "links" just fine.
The stupid question - how do I implement "#include source " in my C++ code so I can actually use the library.So what needs to be done If I want to "link" my main.cpp source code to the library.?
This code passes #include OK , but has "undefined reference " when I try to use the included header library.
#include <QDebug>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "/home/qt/Qt/PROJECTS/TEST_SUB_DIRS_PROJECT/SUB_PROJECT_LIBRARY/c_test_library.h"MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
qDebug(FILE);
qDebug(FUNCTION);
qDebug ("Main window ***********************");
C_TEST_Library *test = new C_TEST_Library;
ui->setupUi(this);
}MainWindow::~MainWindow()
{
delete ui;
}I have "HEADERS " in library .pro - how do I use them in my main.cpp code ?
QT -= gui TEMPLATE = lib DEFINES += SUB_PROJECT_LIBRARY_LIBRARY CONFIG += c++11 SOURCES += \ c_test_library.cpp \ sub_project_library.cpp HEADERS += \ SUB_PROJECT_LIBRARY_global.h \ c_test_library.h \ sub_project_library.h # Default rules for deployment. unix { target.path = /usr/lib } !isEmpty(target.path): INSTALLS += target `` After I get the above solved , I need to decipher this hierarchy ![c94144bf-61bf-4e3f-a70c-3b194588a1ac-image.png](https://ddgobkiprc33d.cloudfront.net/a3172553-0853-45d2-829c-6c4191bbf636.png) Any help would be appreciated.
-
In your main project, you need to add:
INCLUDEPATH += relative/path/to/your/library/headers
With this you will be able to simply
#include <some_header.h>
.Then, to make it link, you also need to have this line:
LIBS += -Lpath/to/your/library -lyour_library_name
With this your linker will know what to do.
-
@sierdzio This is how main .pro looks
TEMPLATE = subdirs
SUBDIRS +=
MAIN_PROJECT
SUB_PROJECT_LIBRARYunix:!macx: LIBS += -L$$OUT_PWD/SUB_PROJECT_LIBRARY/ -lSUB_PROJECT_LIBRARY
INCLUDEPATH += $$PWD/SUB_PROJECT_LIBRARY
DEPENDPATH += $$PWD/SUB_PROJECT_LIBRARYAnd this is the library .pro
QT -= gui
TEMPLATE = lib
DEFINES += SUB_PROJECT_LIBRARY_LIBRARYCONFIG += c++11
SOURCES +=
c_test_library.cpp
sub_project_library.cppHEADERS +=
SUB_PROJECT_LIBRARY_global.h
c_test_library.h
sub_project_library.hDefault rules for deployment.
unix {
target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += targetSo the source "path" you are referring to is already there in main.pro
so are the "headers" in library.proI understand now C uses header and source files and how the are related to each other .
I am missing is how "make" (qmake) extends such relationship.
If I understand you - by adding "path" to .pro file it would just eliminate including path (in maini.cpp) in mine "#include path header" and make it " #include header" only.
That still does not help to resolve
#include (path) header complies but
implementing the stuff in header gives undefined reference.I am missing something very simple and basic here. - not making correct source reference for the library source files.
PS
I think the "linker" has all necessary options - all in main.pro
But I need to resolve the :header(s) references first to prove the liker is OK.edit
I just realized that you have referred to main.pro ADDING #include path to LIBRARY headers - sort of cross reference . I'll try that. -
@AnneRanch said in SUB_DIRS actual implemetation of shared library:
MAIN_PROJECT
This is where your should have
INCLUDEPATH
andLIBS
defined - in your MAIN_PROJECT.qmake
does not see includes from parent (subdirs) project.I am missing something very simple and basic here. - not making correct source reference for the library source files.
When you include a library, source files are completely irrelevant. Your main application needs headers in order to compile (if I understand you well, this part is working right?), and then libraries (.so, .a or .dll) to link it. If you get
undefined reference
(BTW. please paste actual error message) it usually means that linker can't see the binary library file, or that it uses different architecture or is binary incompatible. -
@sierdzio
So what does this do ? It was added AFTER "Add Library" wizard completed .unix:!macx: LIBS += -L$$OUT_PWD/SUB_PROJECT_LIBRARY/ -lSUB_PROJECT_LIBRARY
INCLUDEPATH += $$PWD/SUB_PROJECT_LIBRARY
DEPENDPATH += $$PWD/SUB_PROJECT_LIBRARY**EDIT
Both INCLUDEPATH and DEPENDPATH are in SUB_DIRS .pro file and obviously refer to "sub project " - in this case SUB_PROJECT_LIBRARY
It would be nice to have some discussion what is the purpose of these entries in SUB_DIRS project (.pro) file.**Adding another subproject - plain Q widget - does not add these INCLUDEPATH and DEPENDPATH to reference to the second subproject,
As far as posting the actual error - I am having a big issue with a feature posting irrelevant stuff instead of real errors. Besides I cannot "screen shot " it.
I do not know the official name of the feature - something like " advanced ...
It generally "jumps the gun " and posts stuff before I am done typing the code.
But it helps most of the time so I have learn to live with it.After I actually added the library to SUB_DIRS I have noticed few includes - local to library - and have probably added the wrong one to the main.cpp
-
@AnneRanch I think I found the problem.
I have OK understanding how SUB_DIRS manages multiple projects - in general.BUT
SUB_DIRS primarily / essentially manages SOURCE code of independent projects.
It does not manage that "automatically" right out of the box.SUB_DIRS makes no distinction between plain project source code and
library source code.To include / use ( and that was the original post question ) library it has to be added to SUB_DIRS differently than plain source project.
SUB_DIRS has to do both - library source code management and library compiling.
My problem is - I am trying to implement library SOURCE code - NOT compiled library.
Here is my test code with "the missing code piece" - how to actually use COMPILED library.
#include <QDebug> #include "mainwindow.h" #include "ui_mainwindow.h" #include "/home/qt/Qt/PROJECTS/TEST_SUB_DIRS_PROJECT/SUB_PROJECT_LIBRARY/c_test_library.h" #include "/home/qt/Qt/PROJECTS/TEST_SUB_DIRS_PROJECT/SUB_PROJECT_LIBRARY/sub_project_library.h" // includes with relative path in .pro OK #include "sub_project_library.h" #include "SUB_PROJECT_LIBRARY_global.h" #include "c_test_library.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { qDebug(__FILE__); qDebug(__FUNCTION__); qDebug ("Main window ***********************"); // use library here syntax ?? objective - run C_TEST_Library::testFunction(); wrong syntax - gives undefined symbol error ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; }
-
@AnneRanch I found this link which may give the solution.
https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
After brief scanning of the article it is clear that I need to have an answer to the following.
After working with SUB_DIRS it is clear its primary task is to manage multiple project.
To demonstrate - use SUB_DIRS to create a project and for identification purposes call it " main project".Then use "project" option to add project to newly created SUB_DIRS" project .
I am not using exact option name at this point - maybe add it later.After adding another project to SUB_DIRS there are TWO INDEPENDENT project in the SUB_DIRS. Previously designated "main project " and "first subproject".
These are independent projects AND neither one is aware of each other!
That is where the "problem" is. These projects have no relations , no dependencies etc. ( I have solved that issue )
Now, by SUD_DIRS definition and options - one can "add library" as subproject. The process of adding library is same as adding plain project and the result is same - after adding a library SUB-DIRS has "main project" and "library" - STILL INDEPENDENT OF EACH OTHER AND WITHOUT RELATIONS !
HOWEVER , the above statement is pure theory - to be verified one has to actually USE the added library.
That is a real issue here.
BUT - we can option to "add new subproject " and instead of C++ execrable select "library" . That is definitely different that "add library".
Adding new subproject as type "library" adds SOURCE code etc.
Hence using "add library" adds reference to compiled "stuff" - complied library.
But both options are sill an independent parts of SUB_DIRS, not related to each other.
Any concurring or opposing views / comments would be appreciated.
EDIT
OK in very simple terms
Create SUB_DIRS project - with "main" project of plain application variety.
Add FIRST SUBPROJECT as "new subprojet" - type (C++) "library".
Add "add library" - using just added FIRST SUBPROJECT - hence "internal library".Now the SUB_DIRS has (C++) library source (project) to manage as source and when all make / buidl / create are deliberately bypassed by executing "Run" the SUB_DIRS project .pro file will contain the following addition :
unix:!macx: LIBS += -L$$OUT_PWD/SUB_LIBRARY/ -lSUB_LIBRARY INCLUDEPATH += $$PWD/SUB_LIBRARY message( $$INCLUDEPATH ) DEPENDPATH += $$PWD/SUB_LIBRARY
AND THAT IS THE ONLY INDICATOR THAT SUD-DIRS has access to compiled C++ library added to SUB_DIRS !
UNFORTUNATELY
this "include path " additionINCLUDEPATH += $$PWD/SUB_LIBRARY
message( $$INCLUDEPATH )
DEPENDPATH += $$PWD/SUB_LIBRARYis useless in SUB_DIRS project file.
Moving it to "main project" .pro , where the libray is actually accessed / used , allows to include the library SOURCE header
without having to add path to it.to be continued
-
@AnneRanch Follow-up
I have created new SUD_DIRS project and added plain C++ "library " as subproject.
Then I did "add library" - adding created library as "internal " AKA part of the SUB)DIRS tree pwer above.
And this is the only vible chnage in SUB_DIRS project .pro fileTEMPLATE = subdirs SUBDIRS += \ MAIN \ SUB_LIBRARY message("START DEBUG SUB_LIBRARY added after option add library" ) unix:!macx: LIBS += -L$$OUT_PWD/SUB_LIBRARY/ -lSUB_LIBRARY INCLUDEPATH += $$PWD/SUB_LIBRARY DEPENDPATH += $$PWD/SUB_LIBRARY message("END DEBUG SUB_LIBRARY added after option add library" )
Hence the SUB_DIRS .pro has libs and includes.
I ahver only ONE real sub project - with its .pro file and it executes just fine.
How do I pass the lib and interludes from SUB_DIRS to my only project ( with main.cpp)
And optionaly - why I have the "add libraray" in SUB_DIRS project file and NOT in main subproject ?
SOLVED
Moving "includes" form SUB_DIRS answered ALL THE QUESTIONS.
The newly created library needs to be "add library" to project where it is needed - not to SUB_DIRS project. DUH !
Looking forward to comments...