Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QMAKE: Visibility of variables defined in .pro file with SUBDIRS
Forum Updated to NodeBB v4.3 + New Features

QMAKE: Visibility of variables defined in .pro file with SUBDIRS

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 269 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Robert Hairgrove
    wrote last edited by
    #1

    I am using Qt Creator with QMake, latest version 17.0.2.

    If I have a top-level .pro file with TEMPLATE = SUBDIRS, and I define a variable like this:

    SOURCE_DIR = $${PWD}/src
    

    Is this symbol still visible from the subproject's .pro files? Or are the parsing contexts of the subprojects completely encapsulated?

    1 Reply Last reply
    1
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote last edited by SGaist
      #2

      Hi,

      AFAIK, no.

      To achieve that, you can create a .qmake.conf file in the root directory and put there stuff that should be common or reused in your sub-projects.

      See this thread

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3
      • KH-219DesignK Offline
        KH-219DesignK Offline
        KH-219Design
        wrote last edited by
        #3

        Building on the answer from @SGaist

        I learned the .qmake.conf trick from here: https://wiki.qt.io/QMake-top-level-srcdir-and-builddir

        And I also honed my SUBDIRS approach further with help from: https://www.toptal.com/qt/vital-guide-qmake

        Once you have a top-level .qmake.conf you can define paths that all subsequent subdir pro files can use, and you can combine that with include to do things like:

        !include($$top_srcdir/compiler_flags.pri) { error() }
        

        ^^ CAVEAT: that snippet assumes you define top_srcdir in .qmake.conf

        I definitely recommend making failed include an error (as in the preceding snippet).

        Many examples simplify to include(../commonthing.pri), which can silently fail.

        www.219design.com
        Software | Electrical | Mechanical | Product Design

        1 Reply Last reply
        3
        • R Offline
          R Offline
          Robert Hairgrove
          wrote last edited by Robert Hairgrove
          #4

          @KH-219Design and @SGaist : Thank you very much! This is fantastic information. I assume that the syntax of the .qmake.conf file is the same as that of any .pro file?

          I think my main problem is still not quite solved. I have a project where the directory structure looks like this:

          Project_Dir
            |__app    <== (under source-code management)
               |__src
               |__app.pro <== has "TEMPLATE=app"
               MyApp.pro  <== has "TEMPLATE=subdirs", but is this OK??
            |__3rd_party  <== (also under SCM, but in a different repository)
               |__A_lib
                  |__src
                  A_lib.pro
               |__B_lib
                  |__src
                  B_lib.pro
               |__C_lib
                  |__src
                  C_lib.pro
            |__build  <== (not under SCM)
               |__<QtVersion>
                    |__Debug  <== build folders for "MyApp"
                    |__Release <==  ""
                    |__libs <== (build folder for "A_lib + B_lib + C_lib"
          

          Each of the 3rd party projects is built as a static library. Presently, I have the default build folder in Qt Creator defined so that up to now, everything in 'MyApp' is built in the correct folder under 'Project_Dir/build'. But I include the source code of the libraries directly and up to now was not making static libraries. I can change the build folder for each of the libraries to get what I want, but I have to do that manually in Qt Creator for each library (only the Release configuration is built for the libraries).

          How can I prevent qmake from creating a "build" folder for the libraries under the "3rd_party" folder which is under SCM and direct it to build under "Project_Dir/build/<QtVersion>/libs" instead, without requiring a manual edit of the shadow build folder in Qt Creator? Even with a .qmake.conf file in each folder next to the lib's .pro file, how would that work? I can use OBJECT_DIR etc. to keep out the artifacts of the build, but the directory itself will be created to contain the Makefile.

          Maybe SUBDIRS is not the right way to do this, but using .pri to include the library projects instead of using subprojects?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote last edited by
            #5

            I would avoid having build directories within the sources at all.
            You can use the OUT_PWD variable to abstract the actual build path to put your librairies where you want them.
            You have your MyApp.pro at the wrong level. It should be at the root of your project sources so you can also properly set the build order to have first the static libraries and only after your application built.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            R 1 Reply Last reply
            0
            • SGaistS SGaist

              I would avoid having build directories within the sources at all.
              You can use the OUT_PWD variable to abstract the actual build path to put your librairies where you want them.
              You have your MyApp.pro at the wrong level. It should be at the root of your project sources so you can also properly set the build order to have first the static libraries and only after your application built.

              R Offline
              R Offline
              Robert Hairgrove
              wrote last edited by
              #6

              @SGaist said in QMAKE: Visibility of variables defined in .pro file with SUBDIRS:

              I would avoid having build directories within the sources at all.

              I probably didn't explain the setup as well as I should have, but this is exactly what I am trying to achieve.

              SGaistS 1 Reply Last reply
              0
              • R Robert Hairgrove

                @SGaist said in QMAKE: Visibility of variables defined in .pro file with SUBDIRS:

                I would avoid having build directories within the sources at all.

                I probably didn't explain the setup as well as I should have, but this is exactly what I am trying to achieve.

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote last edited by
                #7

                @Robert-Hairgrove I suspected that but I thought it was worth mentioning.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  Robert Hairgrove
                  wrote last edited by Robert Hairgrove
                  #8

                  I have found a solution which involves two top-level SUBDIRS projects, one "app" project (i.e. with "TEMPLATE = app"), and three "TEMPLATE = lib" subprojects.

                  It's actually quite possible to put the app project file in the same folder as the top-level SUBDIRS project if you use the .file syntax on the target dependencies.

                  Here is the directory structure, similar to my other post above, but a little different:

                  TOP_Project_Dir
                    |__3rd_party
                       |__A
                          |__src
                             |__A_lib.hpp
                             |__A_lib.cpp
                          A_lib.pro
                       |__B  <== (similar to A)
                       |__C  <== (similar to A)
                       Libs.pro
                       .qmake.conf
                    |__app
                       |__lib
                       |__src
                       App.pro
                       Project.pro
                       .qmake.conf
                  |__build
                     |__Project
                        |__Qt-<version>
                           |__Debug
                           |__Release
                  

                  Here is the top-level Project.pro file:

                  TEMPLATE = subdirs
                  SUBDIRS = Libs App
                  
                  lessThan(QT_MAJOR_VERSION,6):CONFIG+=ordered
                  
                  APP_DIR     = $$top_srcdir
                  THIRD_DIR   = $$clean_path($${APP_DIR}/../3rd_party)
                  
                  Libs.file = $${THIRD_DIR}/Libs.pro
                  App.file  = $${APP_DIR}/App.pro
                  
                  App.depends = Libs
                  

                  The Libs.pro file:

                  TEMPLATE = subdirs
                  SUBDIRS = \
                      A/A_lib.pro \
                      B/B_lib.pro \
                      C/C_lib.pro
                  

                  Here it was more convenient to just refer directly to the file paths in the SUBDIRS section.
                  The A_lib.pro file (and almost exactly the same for B and C libraries):

                  CONFIG -= qt
                  TEMPLATE = lib
                  CONFIG += static c++17 release
                  
                  SOURCES += \
                      src/A_lib.cpp
                  
                  HEADERS += \
                      src/A_lib.hpp
                  
                  TARGET = A
                  
                  PROJECT_DIR = $$clean_path($${top_srcdir}/../)
                  APP_DIR     = $${PROJECT_DIR}/app
                  DESTDIR     = $${APP_DIR}/lib
                  

                  Finally, the App.pro file:

                  CONFIG -= qt
                  TEMPLATE = app
                  TARGET = MyApp
                  CONFIG += c++17 console
                  
                  APP_DIR = $${top_srcdir}
                  LIB_DIR = $${APP_DIR}/lib
                  SRC_DIR = $${APP_DIR}/src
                  THIRD_DIR = $$clean_path("$$top_srcdir/../3rd_party")
                  
                  OBJECTS_DIR = $${top_builddir}/.obj
                  MOC_DIR     = $${top_builddir}/.moc
                  RCC_DIR     = $${top_builddir}/.qrc
                  UI_DIR      = $${top_builddir}/.ui
                  DESTDIR     = $${top_builddir}/exec
                  
                  SOURCES += $${SRC_DIR}/theApp.cpp
                  LIBS += -L"$${LIB_DIR}" -lA -lB -lC
                  
                  INCLUDEPATH += \
                      $${THIRD_DIR}/A/src \
                      $${THIRD_DIR}/B/src \
                      $${THIRD_DIR}/C/src
                  

                  Here is the source of A_lib.hpp and A_lib.cpp which is about the same for B and C:

                  // A_lib.hpp
                  #ifndef A_HPP
                  #define A_HPP
                  namespace A {
                    void whoAmI();
                  }
                  #endif
                  // A_lib.cpp
                  #include "A_lib.hpp"
                  #include <iostream>
                  
                  namespace A {
                    void whoAmI() {
                      using namespace std;
                      cout << "I'm in A lib" << endl;
                    }
                  }
                  

                  Finally, theApp.cpp file:

                  #include "A_lib.hpp"
                  #include "B_lib.hpp"
                  #include "C_lib.hpp"
                  
                  int main() {
                    A::whoAmI();
                    B::whoAmI();
                    C::whoAmI();
                  }
                  

                  In the Qt Creator "Default Build Properties" under "Build & Run", I have this template set for the default build directory:

                  ../build/%{Project:Name}/Qt-%{Qt:Version}/%{BuildConfig:Name}
                  

                  This gives me for my little project this build directory in Debug mode:

                  $HOME/code/TOP_Project_Dir/build/Project/Qt-5.15.13/Debug
                  

                  This is nice because "TOP_Project_Dir/3rd_party" and "TOP_Project_Dir/app" are under source-code management ("SCM", I am using Fossil for the real project) but in two different repositories, and everything under "build" gets ignored.

                  The information @KH-219Design and @SGaist gave me was important to making this work. The sticking point, though, was that both of the top-level .pro files with TEMPLATE=subdirs needed to be parallel to each other, i.e. at the same level relative to the TOP_Project_Dir folder. These also need to be under SCM, so if one was on a different level, the build output of one would have gotten in the way of the other.

                  Marking this now as SOLVED!

                  1 Reply Last reply
                  1
                  • R Robert Hairgrove has marked this topic as solved

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved