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

SUBDIRS - Dependencies



  • Hi guys,

    I've set up a SUBDIRS template based on the intructions on this page.

    I have the same folder structure with my top level PRO file set up like this:

    TEMPLATE = subdirs
     
      SUBDIRS = \
                project1 \   # sub-project names
                project2  \
                app
     
      # where to find the sub projects - give the folders
      project2.subdir = src/project2
      project1.subdir  = src/project1
      app.subdir  = src/app
     
      # what subproject depends on others
      app.depends = project1 project2
    

    The problem I'm having is figuring out how to include headers from another sub project. For example my main.cpp is in the 'app' subproject but I cannot include source files from project1,2 (these aren't LIB projects, only source file projects).

    Any thoughts on what I need to do for correct linking?

    Cheers!



  • This other wiki page seems to explain the "LIBS" syntax that you need: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application#Linking_your_application_against_the_shared_library

    ^^ That link shows the capital -L and the lowercase -l tokens (for path and for library name, respectively).


    The rest of this is probably overkill, but you (@rtavakko ) seem to be wading into a similar exploration as I was last year, so here is where I ultimately ended up, once I mastered "LIBS" and "SUBDIRS" and then added pri files into the mix:

    In addition to the Qt wiki page you already read, @rtavakko , I found the following article to be indispensable in my first attempts to configure a SUBDIRS project: https://www.toptal.com/qt/vital-guide-qmake

    For every library that your application links to, you generally (at a minimum) need something like:

    INCLUDEPATH += $${top_srcdir}
    LIBS += -L$$shadowed($$PWD) -lsubmoduleX
    

    As the project grows, if you find yourself pasting those lines into many pro files (because many things need to link to "libsubmoduleX"), then you can put those lines into a pri file (which is a file containing qmake code that you can then include from other pro files).

    In the end, I settled upon a project structure where the pro file for my executable looks like this, and the pri file for the depended-upon lib looks like this.



  • Simply add the path of project1 and project2 to INCLUDEPATH in your app.pro as they are actually independent projects.
    The depends does not do the include and lib thing, only makes them built first.
    Or you can right click app in the left "Projects" panel and select "Add Library..." to choose "Internal library".



  • @Bonnie Thank you! I've tried adding INCLUDEPATH and DEPENDPATH which does solve the problem of visibility but causes a linker error similar to this if I try to use the included classes:

    main.obj:-1: error: LNK2019: unresolved external symbol "public: __cdecl test::test(void)" (??0test@@QEAA@XZ) referenced in function main
    debug\Morph-Pro.exe:-1: error: LNK1120: 1 unresolved externals
    

    Just to clarify project1,2 don't build any library files and only have .h and .cpp files in them.
    So far the only way I've managed to "fix" this was to also add specific files I need to HEADERS and SOURCES in app.pro but I know this is not the right way.



  • @rtavakko
    That's because you haven't done the LIBS part...Just as linking any other libraries...



  • @Bonnie What statement would I need to add for correct linking? My understanding was that you would use LIBS for library files like dlls.

    INCLUDEPATH += $$PWD/../projectx/
    DEPENDPATH += $$PWD/../projectx
    
    LIBS += $$PWD/../projectx/
    

    The statement above produces this error:

    LNK1104: cannot open file 'PROJECTPATH\projectx.obj'
    

  • Lifetime Qt Champion

    @rtavakko Hi,

    You are missing the -L before the path in your LIBS statement.

    Also, unless you are doing in-source builds (you should not), that won't work. You rather want to use the OUT_PWD variable which points the to root of the build folder.



  • @rtavakko
    @SGaist is right.
    And if you haven't change the default output dir of projectx, then I still recommand you to use "Add Library..." -> "Internal library" on app.pro.
    It will set INCLUDEPATH and LIBS for you. Maybe you still need to modify a little, but that should be easier.



  • This other wiki page seems to explain the "LIBS" syntax that you need: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application#Linking_your_application_against_the_shared_library

    ^^ That link shows the capital -L and the lowercase -l tokens (for path and for library name, respectively).


    The rest of this is probably overkill, but you (@rtavakko ) seem to be wading into a similar exploration as I was last year, so here is where I ultimately ended up, once I mastered "LIBS" and "SUBDIRS" and then added pri files into the mix:

    In addition to the Qt wiki page you already read, @rtavakko , I found the following article to be indispensable in my first attempts to configure a SUBDIRS project: https://www.toptal.com/qt/vital-guide-qmake

    For every library that your application links to, you generally (at a minimum) need something like:

    INCLUDEPATH += $${top_srcdir}
    LIBS += -L$$shadowed($$PWD) -lsubmoduleX
    

    As the project grows, if you find yourself pasting those lines into many pro files (because many things need to link to "libsubmoduleX"), then you can put those lines into a pri file (which is a file containing qmake code that you can then include from other pro files).

    In the end, I settled upon a project structure where the pro file for my executable looks like this, and the pri file for the depended-upon lib looks like this.



  • @KH-219Design Your detailed response and the first link you posted made me realize my misunderstanding. I had Project1,2 as 'subdirs' templates when they actually need to be 'lib'.

    What I had in mind was to just list INCLUDEPATH & DEPENDPATH with references to the sources in 'projectx' in the 'app' subproject and have it compile those sources but you can't do that unless you actually add those files as HEADERS / SOURCES which defeats the purpose of a subdirs project.

    Based on the link you posted and @SGaist's response, these are the lines needed in app.pro:

    INCLUDEPATH += $$PWD/../projectx/
    DEPENDPATH += $$PWD/../projectx/
    
    LIBS += -L$$OUT_PWD/../projectx/[debug OR release build folder here] -lprojectx
    

    And this would be projectx.pro (static library is easier to create):

    TEMPLATE = lib
    CONFIG += staticlib
    
    HEADERS += test1.h
    SOURCES += test1.cpp
    

    @Bonnie's suggestion to automatically add the projectx subproject as an internal library also works and allows for release/debug/multiplatform builds.

    @KH-219Design Your suggestion for the .pro and .pri templates sound like the path I eventually need to take when I have more submodules, but for now things are simple so I'll come back to those later.

    Thank you all for your responses!



  • @rtavakko I'm so pleased to hear the working solution! Thanks for sharing the good news :)