qMake: How exactly does qmake interpret the "CONFIG(debug, debug|release)" syntax

25,028

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".

Share:
25,028

Related videos on Youtube

hashDefine
Author by

hashDefine

Updated on July 09, 2022

Comments

  • hashDefine
    hashDefine almost 2 years

    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 "()" ?
  • hashDefine
    hashDefine about 11 years
    Thank you very much for your answer, it is extremely important and helpful. However, I did not understand the part of the "statement evaluation". you mentioned that "CONFIG(debug, debug|release) evaluates to true if CONFIG contains debug etc...", what do you mean by "contains" ? do you mean defined as in CONFIG += debug ? if so, given that I have no such definition in my .pro file, then where this definition is located ? .. another thing, you also defined this:CONFIG += release debug release debug release debug, what does it means to define "debug" and "release" like this ?
  • hashDefine
    hashDefine about 11 years
    please, also excuse my too much questions as I can't find, at all, any internet source that explains it, not to mention your explanation is very simple, concise and clear.
  • Nikos C.
    Nikos C. about 11 years
    @hashDefine Qt Creator can add "release" to CONFIG when calling qmake. For example, if you select "Run qmake" in the "Build" menu and you've set your build to release mode, you can see it passes "CONFIG+=release" as argument to qmake. Since CONFIG can already contain "debug" in it (either because you've put that in your project file yourself, or it might come from an mkspec file), there has to be a way to override it. This is why the "appears last in CONFIG" rule exists. The example I gave was just that though; an example. There's no use in adding both "release" and "debug" to CONFIG yourself.
  • user1914692
    user1914692 over 9 years
    Personally I think debug|release corresponds to debug_and_release
  • Nikos C.
    Nikos C. over 9 years
    @user1914692 A build is either debug or release. Cannot be both.
  • user1914692
    user1914692 over 9 years
    I mean, CONFIG(debug, debug|release) will be true, if we CONFIG debug, or CONFIG(debug_and_release). But anyway, it seems online official document is not very clear.
  • Robin Hsu
    Robin Hsu over 9 years
    @Nikos C.: Could you make it clearer: when you explain CONFIG(debug, debug|release), the expression itself has two 'debug'. When you explain the meaning, could you mark which debug in the expression is referred to for each 'debug' you mentioned in your explanation? Thanks.
  • Nikos C.
    Nikos C. over 9 years
    @RobinHsu From qt-project.org/doc/qt-4.8/…: "As the order of values is important in CONFIG variables (i.e. the last one set will be considered the active config for mutually exclusive values) a second parameter can be used to specify a set of values to consider." So "debug|release" is the set of possible symbols, while "debug" (the first argument) is the symbol that has to occur last for the statement to be true. Yes, qmake is a giant hack, and it's one of the reason why it was replaced by qbs :-)
  • Robin Hsu
    Robin Hsu over 9 years
    @Nikos C.: Got it! Thank you very much. It confused me for so long. BTW, so it means: For the 2nd parameter, "debug|release" is the same as "release|debug". Am I right?
  • Nikos C.
    Nikos C. over 9 years
    @RobinHsu Yes, the order is irrelevant. Well, it should be irrelevant. Better try it to make sure.
  • Cuadue
    Cuadue almost 9 years
    I think a lot of the confusion arises from the fact that qmake uses two different namespaces for functions and variables, then uses the CONFIG() function to access the value of the CONFIG variable, rather than generalized functions e.g. EQUALS(FILTER($$CONFIG, ["debug", "release"]), "debug")
  • YoavKlein
    YoavKlein over 2 years
    @NikosC. so why three times?
  • Nikos C.
    Nikos C. over 2 years
    @YoavKlein It can be four times, even. There's not only debug and release configurations. There's others as well (like a configuration for profiling.)