8

While reading through the documentation for Qt 5.1, and specifically qmake, I was stumped by the explanation given in the documentation for the qmake CONFIG() function. I completely understood the one-argument version of the function, but the two-argument version makes absolutely no sense to me. I think my confusion is coming from the lack of a definition for 'active config' since the Qt 5.1 documentation says the following:

This function can be used to test for variables placed into the CONFIG variable. This is the same as scopes, but has the added advantage that a second parameter can be passed to test for the active config. As the order of values is important in CONFIG variables (that is, 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.

I would greatly appreciate an explanation for this concept of 'active config' as I am completely stumped and cannot make any practical sense out of this second argument.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
C. Springer
  • 173
  • 2
  • 12

1 Answers1

20

The CONFIG variable can contain conflicting options, such as both "release" and "debug". If CONFIG contains both "release" and "debug" at the same time then either "release" or "debug" is effective. The interpretation of conflicting options in CONFIG depends on the order: the last one set will be considered the effective or active config.

Using CONFIG() with one parameter tells you whether an option is present or not in CONFIG variable. If both "release" and "debug" are present then both CONFIG(release) and CONFIG(debug) returns true.

Using CONFIG() with two parameters tells you whether an option is effective or not, is it the active config or not. CONFIG(debug, debug|release) tests whether "debug" is the last (and hence, active) among the "debug" and "release" options.

See this question and answer as well.

EDIT:

I've created a new project with Qt Creator, opened the .pro file generated and added the following line at the bottom: message($${CONFIG}) so that we can see the contents of CONFIG when qmake is run. I show you the whole .pro file:

QT       += core
QT       -= gui
TARGET = QMakeConfigTest
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
message($${CONFIG})

There are two lines where CONFIG is modified, only one option is added and one is removed. Then I've chosen Release Build and run qmake. This is what I see in Compile Output window:

08:53:49: Running steps for project QMakeConfigTest...

08:53:49: Starting: "C:\Qt\Qt5.0.2\5.0.2\msvc2010\bin\qmake.exe" C:\QMakeConfigTest\QMakeConfigTest.pro -r -spec win32-msvc2010

Project MESSAGE: lex yacc debug exceptions depend_includepath testcase_targets import_plugins import_qpa_plugin rtti_off incremental_off windows qt warn_on release link_prl incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe copy_dir_files release shared rtti qpa win32 msvc debug DebugBuild Debug build_pass console

08:53:49: The process "C:\Qt\Qt5.0.2\5.0.2\msvc2010\bin\qmake.exe" exited normally.

08:53:49: Elapsed time: 00:00.

As you can see the CONFIG variable contains a lot of default options beside the console option added in the .pro file. It contains both debug and release twice and debug_and_release once.

Where are these default options coming from? They are defined in .prf and .conf files that are loaded from a directory called mkspecs. So the answer to the question you asked in your comment is that before a .pro file is processed by qmake several other files are pre-processed based on your compiler and platform. These files can add the same options more than once and can add conflicting options to the CONFIG variable.

Here is the contents of C:\Qt\Qt5.0.2\5.0.2\msvc2010\mkspecs\features\default_pre.prf:

# This file is loaded by qmake right before each actual project file.
# Note that evaluating variable assignments from the command line
# still happens in between these two steps.

load(exclusive_builds)
CONFIG = \
    lex yacc debug exceptions depend_includepath \
    testcase_targets import_plugins import_qpa_plugin \
    $$CONFIG

As you can see the first 8 default options are defined in this file.

The contents of C:\Qt\Qt5.0.2\5.0.2\msvc2010\mkspecs\features\win32\default_pre.prf:

CONFIG = rtti_off incremental_off windows $$CONFIG
load(default_pre)

The relevant part of C:\Qt\Qt5.0.2\5.0.2\msvc2010\mkspecs\features\spec_pre.prf:

# This file is loaded by qmake right before loading the qmakespec.
# At this point, the built-in variables have been set up and the project's
# .qmake.super was read (if present).

CONFIG = qt warn_on release link_prl
QT = core gui

Qt Creator runs qmake.exe with the following option: -spec win32-msvc2010. Let's see the qmake manual about the -spec option:

-spec spec: qmake will use spec as a path to platform and compiler information, and the value of QMAKESPEC will be ignored.

The first few lines from C:\Qt\Qt5.0.2\5.0.2\msvc2010\mkspecs\win32-msvc2010\qmake.conf:

#
# qmake configuration for win32-msvc2010
#
# Written for Microsoft Visual C++ 2010
#

MAKEFILE_GENERATOR      = MSBUILD
QMAKE_PLATFORM          = win32
CONFIG                  += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
DEFINES                 += UNICODE WIN32
QMAKE_COMPILER_DEFINES  += _MSC_VER=1600 WIN32
Community
  • 1
  • 1
Bill
  • 11,595
  • 6
  • 44
  • 52
  • I'd like to accept this answer but I think a use-case or other reason why this would ever happen is in order. I don't understand why CONFIG would ever have both 'debug' and 'release' set. There is a separate debug_and_release config option for that case. Could you edit your answer and elaborate a bit more with a reason why this would happen? – C. Springer Aug 11 '13 at 21:12
  • 1
    I think I understand it now. So, the concept of an 'active config' coming into play is mostly dependent on a 3rd party tool or other configuration file (.prf) that might add more to the CONFIG variable?! And that second parameter finds all instances of a group of values in CONFIG, figures out if the first parameter is the 'active config' (last one in the list), and evaluates to true if that is the case. Hopefully I've got this right. Thank you for your explanation...I accepted your answer. – C. Springer Aug 12 '13 at 14:58
  • 1
    @cspringer Thank you very much! There might be other reasons why CONFIG contains conflicting options. I showed you the only reason I know. – Bill Aug 12 '13 at 15:03