Opened 9 years ago

Closed 9 years ago

#227 closed defect (fixed)

Debug verison of QMake used after bootstrap

Reported by: rudi Owned by:
Priority: Feedback Pending Milestone: Qt 4.7
Component: General Version:
Severity: low Keywords:


When the bootstrap version of QMake (generated by configure.cmd) gets replaced by the "real" one (generared from the debug version of the tool is copied to the "bin" directory and therefore used in the subsequent build process.

Change History (17)

comment:1 Changed 9 years ago by Dmitry A. Kuminov

When qmake is built for the second time as part of the 'make' process started from the root of the Qt tree, first, the debug version is generated (and written to "bin" indeed). However, right after that the release version is built and copied to "bin" as well. Which overwrites the previously copied debug version.

So what you say is only possible if you start the build process with 'make debug' which is kind of expected.

If you mean something completely different, please clarify.

comment:2 Changed 9 years ago by Dmitry A. Kuminov

Priority: majorFeedback Pending

comment:3 Changed 9 years ago by Dmitry A. Kuminov

It is also possible that you run 'make -jN' where N > 1. This will cause both the debug build and the release build to run in parallel and the debug target is likely to be finished last in this case. Please check if this is what you have.

Last edited 9 years ago by Dmitry A. Kuminov (previous) (diff)

comment:4 Changed 9 years ago by rudi

Hmm, I didn't do anything special except that I had modified QMake itself before. So it might be possible that I did not clean up all the remains of these tests and that a release version of QMake was built before the debug version. I just updated to the most recent tree and did a "configure". Now the problem is gone.

comment:5 Changed 9 years ago by rudi

O.K. now I know what happened: I modified some QMake source code and built only the release version. Somewhat later, I ran "make" from the root of the Qt tree. This only created the debug version, since the objects for release were already up to date. This debug version will not be replaced until some change in the qmake subtree (or a reconfigure) causes the release objects to be out of date.

comment:6 Changed 9 years ago by Dmitry A. Kuminov

Yes, problems like that are unavoidable when several builds share the same output directory since EXEs (normally) use the same output name which makes it impossible to distinguish which build it belongs to.

The proper way to solve it is to use separate directories for different builds (i.e. shadow builds). I'm now working on configure.cmd to make it (finally) possible for Qt itself.

comment:7 Changed 9 years ago by Dmitry A. Kuminov

While working on the shadow build for Qt, the old issue with the source PWD missing in INCLUDEPATH has appeared again.

Some background. The problem first appeared when I removed PWD (".") from the default (system) include path of GCC (see for a full explanation). This in particular affected cases like the following:


If only "-I tmp" was given to the compiler when compiling "main.cpp" which included "a.h" which included "ui_a.h" which in turn included "b.h" would not work because PWD (i.e. the project dir itself) was not among -I arguments. We had to solve this problem by adding "." to INCLUDEPATH of every .pro file that suffers from that issue. What really bothered me all the time is why other platforms worked well w/o this change. And here comes the light.

The first (and the fun) thing is that, given exactly the same case, the MSVC compiler just works. Probably, because it implicitly adds the directory of the .cpp file being compiled to the list of includes. Note that it works for shadow builds as well (w/o doing any extra includes).

GCC does not do that (neither on OS/2 nor on Linux, I checked) so that an explicit "-I ." is necessary in this case. And guess what, in UnixMakefileGenerator::writeMakeParts(QTextStream &t) (i.e. the Makefile generator used on Unix-like systems) they do just that: add the PWD to the list of includes of every generated Makefile. What a cheat.

More over, the solution used on Linux gracefully handles the shadow build case where the full path to the source directory (not just ".") needs to be added to includes (since building happens in the shadow output dir, not in the source dir).

I think that I will go a third way. Since this looks more like a property of the compiler, I will not hard code it into our GNUMAKE generator but instead place the workaround to the per-compiler qmake.conf (located in mkspecs/os2-g++ in our case). This way, it can be easily adopted to any compiler w/o the need to change qmake.exe.

comment:8 Changed 9 years ago by Dmitry A. Kuminov

The mentioned change is done in r981.

After I'm done with the rest of the shadow build fixes, I will undo all commits where we added "INCLUDEPATH = ." to Qt sources.

comment:9 Changed 9 years ago by rudi

Good. I had several situations, where it was necessary to add "INCLUDEPATH += ." to a *.pro file which worked without that on other platforms. However, on all the nice changes we apply to QMake, we should keep in mind not to enhance it so much that our *.pro files become incompatible with the original.

comment:10 Changed 9 years ago by Dmitry A. Kuminov

Yes, every OS/2 porter of Qt apps has suffered from that. Regarding the compatibility, it's always the top priority. As I said somewhere, I now even tend to keep (or inject) the obvious bugs in the OS/2 version of Qt to make sure we are compatible.

Anyway, the shadow build support is there (r983). What you need to do to make use of it:

  1. Check out a fresh copy of the Qt source tree.
  2. Create a directory somewhere (outside the tree) and enter it.
  3. Start <path_to_Qt_tree>\configure.cmd while staying there.
  4. Do the usual make.


  1. The default build type in case of the shadow build is release (not dual, no debug build at all). If you want to change the build type, you will have to pass command line options to configure.cmd (will add that later).
  2. You will need Perl installed in order to perform the shadow build of Qt. This is because it requires special header processing (basically, creating forward includes in the build tree to the source tree) which is done using the Perl script.

comment:11 Changed 9 years ago by Dmitry A. Kuminov

The next steps:

  1. Fix building the documentation (not directly related to shadow builds, it just turned to be broken, after updating to 4.3.7 perhaps). Done, see comment:14.
  2. Make sure examples and demos build in the shadow.
  3. Support the minimal set of command line options to configure.cmd to be able to choose at least the build type (debug/release). Done in r989.
  4. Remove INCLUDEPATH changes. Done in r987.
  5. Make Qt Creator compatible with the latest changes in the build process. Done. A full rebuild of Qt Creator is still pending though.
  6. Create forwarding includes for .prf files in mkspecs similar to what they do for headers. It's really annoying to maintain two copies and run configure.cmd each time I change anything in there. Impossible, see comment:15.
Last edited 9 years ago by Dmitry A. Kuminov (previous) (diff)

comment:12 Changed 9 years ago by rudi

For 1). take a look at #219. As for the shadow builds: ISTR, that some documentation mentions that the build directory is not allowed to be somewhere outside the tree. Instead they claim that is has to be on the same directory level as the sources. I.e. in a structure like this:

project_root --+-- sources
               +-- build_dir1 (platform desktop)
               +-- build_dir2 (platform symbian)
               +-- ...

I don't know, if this is a requirement for our implementation as well.

comment:13 Changed 9 years ago by Dmitry A. Kuminov

Yes, I already noticed that they symlink it over (copy on Windows). I don't like copying the documentation to each output dir at all so I hope I will be able to solve that somehow. At least I already solved the similar problem for qmake (and know how to do that for mkspecs, see step 6 above).

comment:14 Changed 9 years ago by Dmitry A. Kuminov

Regarding 1. It actually works fine when being out of the source tree, I didn't have to do anything special (other than closing #219 and adding the missing documentation for some OS/2-only methods). The generated documentation looks quite OK and gets nicely shown in e.g. Qt Creator.

BTW, qdoc seems to be kind of dumb. It cannot detect inheritance if both classes are defined within some other class (e.g. QPMMime::DefaultDragWorker? derived from QPMMime::DragWorker?). As a result, the \reimp tags don't work giving the following warning:

D:/Coding/qt/qt4/src/gui/kernel/qmime_pm.cpp:312: Cannot find base function for '\reimp' in cleanup()
    [The function either doesn't exist in any base class with the same signature or it exists but isn't virtual.]

I don't know how to make it work. Let's leave it out for now.

comment:15 Changed 9 years ago by Dmitry A. Kuminov

Unfortunately, there is a bug in qmake which makes it impossible to create forwarding includes for .prf. When <out>/mkspecs/os2/default_pre.prf includes <src>/mkspecs/os2/default_pre.prf and then tries to load(default_pre), qmake thinks that default_pre.prf is already loaded (it should actually first search in <src>/mkspecs, discover that <src>/mkspecs/default_pre.prf is *not* yet loaded and load it). Silly. So we have to live with a stupid copy.

The good news is that Qt actually already supports symlinks, thanks to their emulation in kIBC (at least qmake does that), and if you use kmk instead of make (which is also kLIBC based) it even almost works. "Almost", because some parts of our build process involve CMD.EXE (e.g. emxexpw.cmd and all other REXX scripts) which obviously don't support symlinks.

So we should really, really move to the POSIX tool chain one day.

comment:16 Changed 9 years ago by Dmitry A. Kuminov

Excellent. Our old good friend "fatal error: error writing to lalala.s: Invalid argument" when compiling one of the examples. What a joy. It will never end.

comment:17 Changed 9 years ago by Dmitry A. Kuminov

Resolution: fixed
Status: newclosed

Okay, demos and examples build now. I've also enabled them inn configure by default. Added -nomake and -make options to configure.cmd to select which parts to build if the default is not suitable.

So, enough with the configure stuff for now.

Note: See TracTickets for help on using tickets.