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

SUBDIRS Makefiles are missing dependencies to each other

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: P2: Important P2: Important
    • 5.0.0 Beta 1
    • 5.0.0
    • Build tools: qmake
    • None
    • 575a51663007095c8c4d14295ed6028cc18513f8

      When using a SUBDIRS project, and using either CONFIG+=ordered or (subdir).depends to set dependencies between subdirs, the dependencies are generated between the main (e.g. compilation) subtargets but not between the qmake subtargets.

      This is important because the result of qmake'ing one subdir may use as input the result of qmake'ing another subdir - in particular, this is the case when one subdir creates a prl file which is used by a sibling subdir. In this case, the missing dependency information can cause random build failures.

      Here is an example which demonstrates the problem on Linux.

      Given this project setup:

      diff --git a/dir_one/dir_one.pro b/dir_one/dir_one.pro
      new file mode 100644
      index 0000000..66147a8
      --- /dev/null
      +++ b/dir_one/dir_one.pro
      @@ -0,0 +1,4 @@
      +TEMPLATE = lib
      +CONFIG += create_prl
      +CONFIG -= debug_and_release
      +PRL_EXPORT_DEFINES = dir_one_prl_is_loaded
      diff --git a/dir_two/dir_two.pro b/dir_two/dir_two.pro
      new file mode 100644
      index 0000000..61f72e3
      --- /dev/null
      +++ b/dir_two/dir_two.pro
      @@ -0,0 +1,4 @@
      +TEMPLATE = lib
      +CONFIG += link_prl
      +LIBS += -L../dir_one -ldir_one
      +SOURCES += lib.cpp
      diff --git a/dir_two/lib.cpp b/dir_two/lib.cpp
      new file mode 100644
      index 0000000..a3545ae
      --- /dev/null
      +++ b/dir_two/lib.cpp
      @@ -0,0 +1,8 @@
      +int func()
      +{
      +#ifndef dir_one_prl_is_loaded
      +#   error wrong - libdir_one.prl was not processed when dir_two.pro was qmaked
      +#else
      +    return 0;
      +#endif
      +}
      diff --git a/prltest.pro b/prltest.pro
      new file mode 100644
      index 0000000..dfb38eb
      --- /dev/null
      +++ b/prltest.pro
      @@ -0,0 +1,3 @@
      +TEMPLATE = subdirs
      +dir_two.depends = dir_one
      +SUBDIRS = dir_one dir_two
      

      For dir_two to successfully compile, dir_one must be qmaked before dir_two.
      However, nothing in the generated makefile causes this to happen, despite the dir_two.depends = dir_one line.

      make -j1 works fine:

      [rmcgover@bq-menoetius prltest]$ i=0; while test $i -lt 10 && git clean -dqffx . && qmake CONFIG+=silent && make -s -j1; do echo -e "\nOK $i\n"; i=$(expr $i + 1); done
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 0
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 1
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 2
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 3
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 4
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 5
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 6
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 7
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 8
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 9
      
      

      make -j20 randomly fails (depends whether or not libdir_one.prl was written before qmake on dir_two.pro tried to read it)

      [rmcgover@bq-menoetius prltest]$ i=0; while test $i -lt 10 && git clean -dqffx . && qmake CONFIG+=silent && make -s -j20; do echo -e "\nOK $i\n"; i=$(expr $i + 1); done
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      linking libdir_two.so.1.0.0
      indexing libdir_two.so.1.0.0 for gdb
      
      OK 0
      
      linking libdir_one.so.1.0.0
      indexing libdir_one.so.1.0.0 for gdb
      compiling lib.cpp
      lib.cpp:4:5: error: #error wrong - libdir_one.prl was not processed when dir_two.pro was qmaked
      make[1]: *** [lib.o] Error 1
      make: *** [sub-dir_two-make_default] Error 2
      

      This is breaking some Windows builds of Qt5 - e.g. see http://testresults.qt-project.org/ci/QtDeclarative_master_Integration/build_01208/win32-msvc2010_Windows_7/log.txt.gz , which fails because qtdeclarative/src/quick/quick.pro is qmaked before qtbase/lib/QtDeclarative.prl has been written.

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            buddenha Oswald Buddenhagen
            rmcgover Rohan McGovern (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes