Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-45706

qmake -r ignores SUBDIRS' .depends

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.4.1, 5.5.0 Alpha
    • Build tools: qmake
    • None
    • Windows 7, VS2010 (msbuild) , QtCreator (jom / nmake)

    Description

      Sorry, this is getting a long one.

      So, Summary first:
      template = subdirs
      projects are not handled as described in the Qt 5 docs.

      I took the time to check some constellations for creating subdir projects for Windows using the QtCreator (so nmake/jom) and MSVS2010 (msbuild) at the same time.

      Basic methods in this game are:

      • .depends attribute
      • CONFIG += ordered

      I attached my toy project, which consist of one application "app" and two libraries: "lib" and "lib2".

      The deal is: To build app, the two libraries lib and lib2 must be build first.

      Two Documented Ways

      So, there are two documented ways to do so with template subdirs as noted in http://doc.qt.io/qt-4.8/qmake-variable-reference.html#subdirs and http://doc.qt.io/qt-5.4/qmake-variable-reference.html#subdirs. These docs slightly differ in details. But with 5.4 there are mainly to methods described there:

      • One is called the (Kitten killing ) CONFIG += ordered method, which should process project after project as listed in the SUBDIRS variable.
        But in 4.8, this method was ruled out for MSVS2010. In the docs for 5.4, this method is not ruled out for VS anymore! We'll give it a try.
      • The other method is more direct by expicitly writing down dependencies via ".depends" attributes. This is documented as the more clever method, as it allows parallel processing of independent projects.

      This sounds rather simple: method one or method two.
      Well, it is not!

      The infamous players

      Additional players that come along are not documented in this context. And for good reason, as they should not be players in this methods game. So I name this influence taking a (or many) bug(s).

      These players are:

      • The order in which the subprojects are listed in SUBDIRS ... even for the .depends case (for the ordered it should be clear, but isn't, too)
      • build_pass ... this is a proposed technique to generate a different target name e.g. for the debug version of your app.
        build_pass:CONFIG(debug,   release|debug): TARGET=libd
        build_pass:CONFIG(release, release|debug): TARGET=lib
        

      Check different methods with the players

      Attached you will find my little subdirs example with different constellations. All can be switch by a variable "M" (as in method) you give on the command line with qmake.

      qmake -tp vc -r "M=2" # build method 2 for VS2010 (.sln, .vcxproj) 
      qmake -r "M=2"        # build method 2 for nmake / jom (Makefile)
      

      In total there are 6 (yes you read right – in words: six) different methods.
      All are a little different.

      All was tested with qmake of Qt 5.4.1 (at least ... some also with Qt 4.8 and Qt 5.5)

      So to follow the listing that comes now I suggest you

      • unzip the attachment
      • start a Windows VS2010 cmd tool with Qt 5.4.1 setup
      • give qmake a go with with -tp vc and without.
      • have a look at the .sln file and at the Makefile respectively for details

      A long detailed output of these process is attached, if you want to look at my results.

      Method 1

      Setup:
      • method: .depends
      • SUBDIRS: "correctly" ordered: lib lib2 app
      • build_pass: active
      Result:
      • MSVS2010: does detect dependencies.
      • QtCreator: does detect dependencies.
      Summary:

      Pro: This is the way to go. lib and lib2 are build in parallel before app is build.
      Con: The order of projects must be "correct", else MSVS2010 fails (see method 2).
      Con: This method is no option for Qt 4.8 MSVS2010 as .depends does not seem to work for Qt 4.8 qmake.

      Method 2

      Setup
      • method: .depends
      • SUBDIRS: "not nicely" ordered: app lib lib2
      • build_pass: active

      Comment: the .depends should pull everything straight, right? At least qmake should just push the dependencies to the build tools via Makefile or the VS2010 .sln file. And let them organize the build order from this. Well, see the results...

      Results
      • MSVS2010: does not detect dependencies.
      • QtCreator: does detect dependencies.
      Summary

      This was just found by accident. The vcxproj and sln generators are confused by the listing order of SUBDIRS. They must not, because the dependency tree is totally defined by the .depends attributes.
      If qmake would check for cyclic dependencies (like lib_a needs lib_b and lib_b needs lib_a) that would be great, but the build tools (nmake, jom, msbuild) should anyway.... blame it on them if it does not work. But I do not want to resolve the build order by myself in SUBDIRS. This is mainly why I want to use .depends.

      Method 3

      Setup
      • method: no depends are given
      • SUBDIRS: "not nicely" ordered: app lib lib2
      • build_pass: active

      Comment: this is a kind of anti-method as it is not using .depends, nor is it using CONFIG +=ordered. It is mainly here to check if everything fails ....

      Result
      • MSVS2010: does not detect dependencies.
      • QtCreator: does not detect dependencies.
      Summary

      This is ok. Both toolchains start building everything in parallel (jom, msbuild) (nmake does not have this feature). But jom might be stopped by a race condition (app wants to be linked, when lib is not build).
      msbuild however is clever enough to analyse all the the vcproj and sees that it has to wait for the libs.... wow. Is this really true?

      Method 4

      Setup
      • method: no depends are given
      • SUBDIRS: "not nicely" ordered: app lib lib2
      • build_pass: inactive

      Comment: Same as Mehtod 3, but now build_pass not used anymore:

      # no build_pass anymore
      CONFIG(debug,   release|debug): TARGET=libd
      CONFIG(release, release|debug): TARGET=lib
      
      Result
      • MSVS2010: does detect dependencies !!!
      • QtCreator: does not detect dependencies.

      Comment: Here a special .pro file pattern is still active that is documented in the SUBDIRS section of qmake of Qt 4.8 http://doc.qt.io/qt-4.8/qmake-variable-reference.html#ordered-targets-and-visual-studio-solution-files. Qt 5.4 seems to still manage this even though there was discussion about removing this https://codereview.qt-project.org/#/c/24595/. And this feature is not documented in Qt 5.4 anymore.

      Summary

      Well, this seems to be a kind of legacy mode for MSVS2010. But this is confusing if you start with Qt5 use MSVS2010 and then find it breaking on QtCreator or mingw or gcc (Linux) .....

      Method 5

      Setup
      • method: CONFIG += ordered
      • SUBDIRS: ordered: lib lib2 app
      • build_pass: active

      Comment: So as the documentation for Qt 5.4 does not tell anymore, that ordered is no option for VS2010 anymore, we have to assume it works now.... and on top we use the build_pass again.... but hey, we have a nice order in SUBDIRS, at least.

      Result
      • MSVS2010: does not detect dependencies or build order !!!
      • QtCreator: does build nice processing order.

      Comment: MSVS2010 just builds everything in parallel. Again - somehow - it manages to wait before app linking until the libs are build. jom processes project after project in the order given by the listing in SUBDIRS, as documented.

      Summary

      The documentation is not correct about removing the warning about MSVS2010 in the CONFIG += ordered. qmake does not create dependency entries in .sln that would generate a sequential ordered processing.

      Method 6

      Setup
      • method: CONFIG += ordered
      • SUBDIRS: ordered: lib lib2 app
      • build_pass: inactive

      Comment: The same as in Method 5 but now with inactive build_pass again.

      Result
      • MSVC2010: does detect dependencies !!! Again... (see Method4)
      • QtCreator: does build in the order given in the SUBDIRS variable.

      Comment: Again the missing build_pass allows in the MSVC2010 case to auto-detect the the dependencies (see Method 4 comment).

      Summary

      Very inconsistent. QtCreator project after project, MSVC2010 in parallel. The documentation of Qt 5.4 tells us other things....

      Summary

      It took a lot of time, to see what the best fitting method would be in my case. I have projects still in 4.8 and some new in 5.4. Some have to work in MSVS2010 (legacy CI msbuild scripts) others in QtCreator ... well ....

      I would like to take the ".depends" method described in the Qt5 documents, but this is not working with MSVS2010 and Qt 4.8. When using the build_pass it is getting worse... MSVS2010 auto dependency detection then does not work at all, but this auto-dependency seems to be the only way for dependency setting with 4.8....

      At the moment we use actually Method 6: QtCreator with ordered (4.8.6 + 5.4.1), MSVS is ignoring this and due to the lib pattern we use we have luckily the auto-detection feature (4.8.5 + 5.4.1).

      What would be best (in my eyes) would be to have a working depends for the MSVS2010 (so not failing in Method2) for 4.8.7 and 5.4.2 ongoing. The Makefile generators seems to behave well.

      Thank you, if you read down to this line

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-45706
          # Subject Branch Project Status CR V

          Activity

            People

              qtbuildsystem Qt Build System Team
              moellney Michael Möllney
              Votes:
              8 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes