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

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.

  • Moderators

    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_LIBRARY

    unix:!macx: LIBS += -L$$OUT_PWD/SUB_PROJECT_LIBRARY/ -lSUB_PROJECT_LIBRARY

    INCLUDEPATH += $$PWD/SUB_PROJECT_LIBRARY
    DEPENDPATH += $$PWD/SUB_PROJECT_LIBRARY

    And this is the library .pro

    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

    So the source "path" you are referring to is already there in main.pro
    so are the "headers" in library.pro

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


  • Moderators

    @AnneRanch said in SUB_DIRS actual implemetation of shared library:

    MAIN_PROJECT

    This is where your should have INCLUDEPATH and LIBS 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 " addition

    INCLUDEPATH += $$PWD/SUB_LIBRARY
    message( $$INCLUDEPATH )
    DEPENDPATH += $$PWD/SUB_LIBRARY

    is 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 file

    TEMPLATE = 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...


Log in to reply