Results 1 to 7 of 7

Thread: qmake generates bogus Makefiles

  1. #1
    Join Date
    Jan 2011
    Posts
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default qmake generates bogus Makefiles

    Hi,

    I use Qt 4.7.3 on Linux, and I am facing weird qmake behavior. I have tried to narrow the problem down to the following minimal example:

    I have a directory, qmake_example, which contains two files:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. release: DESTDIR = release
    5. debug: DESTDIR = debug
    6.  
    7. SOURCES += main.cpp
    8.  
    9. $ cat main.cpp
    10. int main()
    11. {
    12. return 0;
    13. }
    To copy to clipboard, switch view to plain text mode 

    As you can see:
    1. I want to be able to build the project in debug and/or release mode.
    2. I want to keep the generated binaries in build subdirectories separate from the source directory.

    First I run qmake, which generates the expected Makefiles and build subdirectories:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    3. $ qmake
    4. $ ls
    5. debug Makefile Makefile.Release release
    6. main.cpp Makefile.Debug qmake_example.pro
    To copy to clipboard, switch view to plain text mode 

    Then I run make to generate both debug and release builds:

    Qt Code:
    1. $ make debug release # I also tried the equivalent 'make all'
    2. <g++'s output lines, no warnings, no errors>
    To copy to clipboard, switch view to plain text mode 

    But then, surprise: the binary is generated only for debug:

    Qt Code:
    1. $ ls debug/
    2. main.o qmake_example
    3. $ ls release/
    4. main.o
    To copy to clipboard, switch view to plain text mode 

    The problem is in Makefile.Release, which contains (among other lines):

    Qt Code:
    1. # Makefile for building: debug/qmake_example
    2. [more lines]
    3. DESTDIR = debug/
    4. TARGET = debug/qmake_example
    5. [more lines]
    6. @$(CHK_DIR_EXISTS) debug/ || $(MKDIR) debug/
    7. [more lines]
    To copy to clipboard, switch view to plain text mode 

    What am I doing wrong? How should I write my .pro file / invke qmake in order to have Makefile.Release refer to directory release instead of debug?

  2. #2
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: qmake generates bogus Makefiles

    Here's what I use in my qmake pro files and works for me:
    Qt Code:
    1. CONFIG(debug, debug|release) {
    2. DESTDIR = build/debug
    3. } else {
    4. DESTDIR = build/release
    5. }
    To copy to clipboard, switch view to plain text mode 
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  3. #3
    Join Date
    Jan 2011
    Posts
    7
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: qmake generates bogus Makefiles

    Thank you for your suggestion, which helped me discover the solution through a few quirks:

    I change qmake_example.pro to:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = build/debug
    6. } else {
    7. DESTDIR = build/release
    8. }
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    and start from a clean directory:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    To copy to clipboard, switch view to plain text mode 
    Then:

    Qt Code:
    1. $ qmake
    2. $ ls
    3. build main.cpp Makefile.Debug qmake_example.pro
    4. debug Makefile Makefile.Release release
    5. $ ls build/
    6. debug release
    To copy to clipboard, switch view to plain text mode 
    First surprise: in addition to the expected build/debug and build/release, qmake also created directories ./debug and ./release.

    Then:

    Qt Code:
    1. $ make debug release
    2. <g++'s output lines, no warnings, no errors>
    3. $ ls build/debug/
    4. qmake_example
    5. $ ls build/release/
    6. qmake_example
    7. $ ls debug/
    8. main.o
    9. $ ls release/
    10. main.o
    To copy to clipboard, switch view to plain text mode 
    Second surprise: the executable binaries did go to build/debug and build/release, but the object files went to ./debug and ./release!

    New experiment, this time specifying OBJECTS_DIR:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = build/debug
    6. } else {
    7. DESTDIR = build/release
    8. }
    9.  
    10. OBJECTS_DIR = $$DESTDIR
    11.  
    12. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    Starting from a clean state:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    To copy to clipboard, switch view to plain text mode 
    qmake still creates directories build/debug, build/release, ./debug, and ./release:

    Qt Code:
    1. $ qmake
    2. $ ls
    3. build main.cpp Makefile.Debug qmake_example.pro
    4. debug Makefile Makefile.Release release
    To copy to clipboard, switch view to plain text mode 
    but this time at least the object files go to their correct directories:

    Qt Code:
    1. $ make debug release
    2. <g++'s output lines, no warnings, no errors>
    3. $ ls build/debug/
    4. main.o qmake_example
    5. $ ls build/release/
    6. main.o qmake_example
    7. $ ls debug/
    8. $ ls release/
    To copy to clipboard, switch view to plain text mode 
    Only remaining problem: two useless-but-still-created-by-qmake directories, ./debug and ./release.

    But now, eliminating the intermediate directory ./build in DESTDIR:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = debug
    6. } else {
    7. DESTDIR = release
    8. }
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    solves the problem:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    3. $ qmake
    4. $ ls
    5. debug Makefile Makefile.Release release
    6. main.cpp Makefile.Debug qmake_example.pro
    7. $ make debug release
    8. <g++'s output lines, no warnings, no errors>
    9. $ ls debug/
    10. main.o qmake_example
    11. $ ls release/
    12. main.o qmake_example
    To copy to clipboard, switch view to plain text mode 
    The executable binary files and the object files finally go to their intended directories, and no extra directories are created.

    Thank you again for pointing me in the right direction. That kind of experience, however, makes me doubt about qmake's quality.

    Thank you for your suggestion, which helped me discover the solution through a few quirks:

    I change qmake_example.pro to:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = build/debug
    6. } else {
    7. DESTDIR = build/release
    8. }
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    and start from a clean directory:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    To copy to clipboard, switch view to plain text mode 
    Then:

    Qt Code:
    1. $ qmake
    2. $ ls
    3. build main.cpp Makefile.Debug qmake_example.pro
    4. debug Makefile Makefile.Release release
    5. $ ls build/
    6. debug release
    To copy to clipboard, switch view to plain text mode 
    First surprise: in addition to the expected build/debug and build/release, qmake also created directories ./debug and ./release.

    Then:

    Qt Code:
    1. $ make debug release
    2. <g++'s output lines, no warnings, no errors>
    3. $ ls build/debug/
    4. qmake_example
    5. $ ls build/release/
    6. qmake_example
    7. $ ls debug/
    8. main.o
    9. $ ls release/
    10. main.o
    To copy to clipboard, switch view to plain text mode 
    Second surprise: the executable binaries did go to build/debug and build/release, but the object files went to ./debug and ./release!

    New experiment, this time specifying OBJECTS_DIR:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = build/debug
    6. } else {
    7. DESTDIR = build/release
    8. }
    9.  
    10. OBJECTS_DIR = $$DESTDIR
    11.  
    12. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    Starting from a clean state:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    To copy to clipboard, switch view to plain text mode 
    qmake still creates directories build/debug, build/release, ./debug, and ./release:

    Qt Code:
    1. $ qmake
    2. $ ls
    3. build main.cpp Makefile.Debug qmake_example.pro
    4. debug Makefile Makefile.Release release
    To copy to clipboard, switch view to plain text mode 
    but this time at least the object files go to their correct directories:

    Qt Code:
    1. $ make debug release
    2. <g++'s output lines, no warnings, no errors>
    3. $ ls build/debug/
    4. main.o qmake_example
    5. $ ls build/release/
    6. main.o qmake_example
    7. $ ls debug/
    8. $ ls release/
    To copy to clipboard, switch view to plain text mode 
    Only remaining problem: two useless-but-still-created-by-qmake directories, ./debug and ./release.

    But now, eliminating the intermediate directory ./build in DESTDIR:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = debug
    6. } else {
    7. DESTDIR = release
    8. }
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    solves the problem:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    3. $ qmake
    4. $ ls
    5. debug Makefile Makefile.Release release
    6. main.cpp Makefile.Debug qmake_example.pro
    7. $ make debug release
    8. <g++'s output lines, no warnings, no errors>
    9. $ ls debug/
    10. main.o qmake_example
    11. $ ls release/
    12. main.o qmake_example
    To copy to clipboard, switch view to plain text mode 
    The executable binary files and the object files finally go to their intended directories, and no extra directories are created.

    Thank you again for pointing me in the right direction. That kind of experience, however, makes me doubt about qmake's quality.

    Thank you for your suggestion, which helped me discover the solution through a few quirks:

    I change qmake_example.pro to:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = build/debug
    6. } else {
    7. DESTDIR = build/release
    8. }
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    and start from a clean directory:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    To copy to clipboard, switch view to plain text mode 
    Then:

    Qt Code:
    1. $ qmake
    2. $ ls
    3. build main.cpp Makefile.Debug qmake_example.pro
    4. debug Makefile Makefile.Release release
    5. $ ls build/
    6. debug release
    To copy to clipboard, switch view to plain text mode 
    First surprise: in addition to the expected build/debug and build/release, qmake also created directories ./debug and ./release.

    Then:

    Qt Code:
    1. $ make debug release
    2. <g++'s output lines, no warnings, no errors>
    3. $ ls build/debug/
    4. qmake_example
    5. $ ls build/release/
    6. qmake_example
    7. $ ls debug/
    8. main.o
    9. $ ls release/
    10. main.o
    To copy to clipboard, switch view to plain text mode 
    Second surprise: the executable binaries did go to build/debug and build/release, but the object files went to ./debug and ./release!

    New experiment, this time specifying OBJECTS_DIR:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = build/debug
    6. } else {
    7. DESTDIR = build/release
    8. }
    9.  
    10. OBJECTS_DIR = $$DESTDIR
    11.  
    12. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    Starting from a clean state:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    To copy to clipboard, switch view to plain text mode 
    qmake still creates directories build/debug, build/release, ./debug, and ./release:

    Qt Code:
    1. $ qmake
    2. $ ls
    3. build main.cpp Makefile.Debug qmake_example.pro
    4. debug Makefile Makefile.Release release
    To copy to clipboard, switch view to plain text mode 
    but this time at least the object files go to their correct directories:

    Qt Code:
    1. $ make debug release
    2. <g++'s output lines, no warnings, no errors>
    3. $ ls build/debug/
    4. main.o qmake_example
    5. $ ls build/release/
    6. main.o qmake_example
    7. $ ls debug/
    8. $ ls release/
    To copy to clipboard, switch view to plain text mode 
    Only remaining problem: two useless-but-still-created-by-qmake directories, ./debug and ./release.

    But now, eliminating the intermediate directory ./build in DESTDIR:

    Qt Code:
    1. $ cat qmake_example.pro
    2. CONFIG += debug_and_release
    3.  
    4. CONFIG(debug, debug|release) {
    5. DESTDIR = debug
    6. } else {
    7. DESTDIR = release
    8. }
    9.  
    10. SOURCES += main.cpp
    To copy to clipboard, switch view to plain text mode 
    solves the problem:

    Qt Code:
    1. $ ls
    2. main.cpp qmake_example.pro
    3. $ qmake
    4. $ ls
    5. debug Makefile Makefile.Release release
    6. main.cpp Makefile.Debug qmake_example.pro
    7. $ make debug release
    8. <g++'s output lines, no warnings, no errors>
    9. $ ls debug/
    10. main.o qmake_example
    11. $ ls release/
    12. main.o qmake_example
    To copy to clipboard, switch view to plain text mode 
    The executable binary files and the object files finally go to their intended directories, and no extra directories are created.

    Thank you again for pointing me in the right direction. That kind of experience, however, makes me doubt about qmake's quality.


    Added after 52 minutes:


    Latest news:

    The example I posted was minimalistic. Our real project also generates moc_*.cpp files and ui_*.h files.

    We just discovered that the moc_*.cpp files are generated in their correct directory (debug or release), but the ui_*.h files are generated in the top-level directory (where the source code resides).

    Fortunately, adding this directive to our .pro file:

    Qt Code:
    1. UI_DIR = $$DESTDIR
    To copy to clipboard, switch view to plain text mode 
    fixes the problem.

    Several words are popping to my mind right now to describe qmake, but I am afraid the rules of this forum do not allow me to share my thoughts.
    Last edited by dave2; 24th September 2015 at 09:03.

  4. #4
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: qmake generates bogus Makefiles

    Heh, I feel your pain. I also add the following directives to all of my qmake pro files that neatly tucks the generated "stuff" out of the way in the build directories:
    Qt Code:
    1. OBJECTS_DIR = $${DESTDIR}/.generatedfiles
    2. MOC_DIR = $${DESTDIR}/.generatedfiles
    3. RCC_DIR = $${DESTDIR}/.generatedfiles
    4. UI_DIR = $${DESTDIR}/.generatedfiles
    To copy to clipboard, switch view to plain text mode 
    Sorry for the time you spent figuring all that out on your own! Once you get a little more experience, I think you'll find qmake is pretty handy but certainly takes some getting used to...
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: qmake generates bogus Makefiles

    I usually just run qmake as many times as I need different built options.

    E.g. create a directory for the debug build, run qmake from there with CONFIG += debug.
    If I need a release build, same for release.
    If I need a third build, again.

    Makes it easy to have builds of various types and doesn't require to build all of them all the time. No point in wasting time building a version you are currently not needing anyway.

    And likely using CMake :-)
    QMake is really nice for simple, self contained, programs and has a really nice and easy to understand syntax.
    Beginner friendly, but limited for advanced use.

    Cheers,
    _

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qmake generates bogus Makefiles

    Bootstrapping myself up into CMake competency at this very moment. I need to maintain a shared library that is compiled and deployed on Win32, Win64, linux, OSX, and Android ARM, along with test programs deployed on Windows. Prior to this, the Windows, linux, and Mac builds were all done on separate machines. Since CMake inherently supports cross-compilation, all except Mac can now be done under Windows. And when I find an OSX compiler that runs under windows, that will be added too.

    But wow, what an overwhelming API to learn.

  7. #7
    Join Date
    Oct 2012
    Posts
    132
    Thanks
    10
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: qmake generates bogus Makefiles

    I also prefer running qmake for each configuration.

    Since CMake inherently supports cross-compilation
    You can also do cross-compilation with QMake. I actually build all my Windows binaries under Arch Linux with mingw-w64.

    But I think it's true, QMake is limited for advanced use. I'm currently having problems with adding a custom compiler to generate icon files when building under/for Windows. Maybe I will also switch to CMake but you say it, it has an overwhelming API.

Similar Threads

  1. Enabling MakeFiles Through .pro files of Qt
    By zgulser in forum Qt Programming
    Replies: 2
    Last Post: 15th May 2012, 00:47
  2. Replies: 12
    Last Post: 7th July 2009, 18:32
  3. Generated Makefiles clean-up
    By tora in forum Qt Programming
    Replies: 3
    Last Post: 4th June 2009, 12:45
  4. qmake does not create visual studio makefiles
    By AlphaWolf in forum Installation and Deployment
    Replies: 2
    Last Post: 6th March 2009, 18:02
  5. Replies: 1
    Last Post: 11th January 2006, 15:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.