Qt – qMake: How exactly does qmake interpret the “CONFIG(debug, debug|release)” syntax

qmakeqtqt-creator

I read though HERE, yet I still don't understand the syntax of the qmake CONFIG variable. for example, if I have the following CONFIG settings in my .pro file:

CONFIG(debug, debug|release) {
    message("debug mode")
}else {
    message("release mode")
}

then, when running qmake, the following will be displayed in the Compile Output in Qt-Creator:

Project MESSAGE: debug mode
Project MESSAGE: debug mode
Project MESSAGE: release mode

knowing that I am building my project in a "debug mode", then my questions are:

  • why not showing the "debug mode" message only ? and why not showing it just once ?
  • Then, since I am building in a "debug mode", why the message "Project MESSAGE: release mode" is displayed ?
  • Exactly, what the syntax: CONFIG(debug, debug|release) really means? does it means that build in a debug mode, then again build in a debug mode and lastly build in a release mode ? I know that these brackets "{}" means a scope (old link was died, recommend scope) but how qmake interpret what is inside these brackets "()" ?

Best Solution

In the article you linked to, it's said in the very beginning that the project file is processed three times. This should answer your first question; since it's processed three times, your message() is executed three times too. Why is it processed multiple times? Because qmake does not build your project! It only generates build instructions which are then used to actually build the project. In order to generate build instructions for all possible configurations, it needs to process the project file multiple times, one time for each configuration.

For your second question: your project is built only in debug mode if that's what you selected, but build instructions are created for release mode too, as already mentioned above. When using "make" with mingw for example (rather than Visual Studio), you get two Makefiles: Makefile.Release and Makefile.Debug. When it generates the release makefile, that's when "release mode" is printed.

Finally, CONFIG(debug, debug|release) evaluates to true if CONFIG contains "debug" but not "release", or if it contains both "debug" and "release" but "release" doesn't appear after the last occurrence of "debug". For example you might have this:

CONFIG += release debug release debug release debug

Since the last "debug" comes after the last "release", CONFIG(debug, debug|release) is true.

The first argument of CONFIG() ("debug" in this case) is the value that has to appear last. The second argument ("debug|release") is the set of values that the first argument is checked against.

Translating that to English would give something like this: evaluate to true if "debug" appears at least once and, in case "release" appears too, the last appearance of "debug" comes after the last appearance of "release".

Related Question