Hi,
here’s the promised look at the details of the new system, in case you need to
implement your own configure tests or want to add configurability to Qt. We now
have one global configuration file qtbase/configure.json, that contains the
details about how Qt can be configured. Actually I’m slightly lying with that,
as there also is a configure.pri file that contains some qmake methods to
handle special cases (specialised tests our output handling).
You can find the infrastructure for the whole system in qt_configure.prf. The
system basically works through two main systems.
The first one is a callback infrastructure, where all “type” fields provided in
the json file actually refer to callback functions in qmake that do the actual
handling. This allows you to e.g. Implement your own custom test function in a
.pri file and refer to that from the json. qt_configure has callbacks for the
most common tasks, so you won’t need this feature in most cases. If you want to
know how such custom callbacks can look like, have a look at configure.pri.
The other central piece is an expression evaluator, that is being used to
evaluate conditions. It allows you to test for rather complex conditions (like
e.g. “config.win32 && tests.mysql && features.opengl”) and is being used in
many places. The evaluator understands boolean operators (!, && and ||),
comparison operators (== and !=), braces and different types of arguments:
frue/false: boolean values
‘foo’: The string literal foo
config.foo: Variables in the qmake CONFIG var (usually used for platform
dependent stuff like config.unix)
tests.foo: Boolean whether the test foo succeeded
tests.foo.bar: Variable bar, set by tests.foo
features.foo: boolean whether feature foo is available
features.foo.bar: variable bar set by features.foo
arch.foo: architecture (like x86, arm, etc)
input.foo: input variable (set by command line handling)
far.foo: Any variable set in qmake
call.foo: return value of the replace function foo in qmake
This gives you quite some options to define conditions and dependencies between
features. The system automatically runs the configure test, if you ask for
tests.foo, so dependency handling is fully transparent.
Now let’s have a look at configure.json:
The file contains a couple of sections. The first one is called “files”, and
contains definitions for the output files. You should not need to touch this
one.
The next section contains the command line parameters that you can pass to the
configuration system. It basically defines the valid command line arguments
that configure will recognise. They are being mapped to a config.input.option
value in qmake, that is then being used in the next step of defining the
features we will use for Qt.
Typical entries looks like
"harfbuzz": { "type": "enum", "values": [ "no", "qt", "system" ] },
"headersclean": "boolean",
This means harfbuzz is an option that can take a selection of args
(-no/-qt/-system), whereas headersclean is a boolean argument (-headersclean
and -no-headersclean accepted). The second form is a shorthand for
"headersclean”: { “type”: “boolean” }
Note that the type variable refers to a callback. In this case a test function
qtConfCommandline_boolean.
Then comes a section with tests. Those define all the configure tests that so
far have been executed by the shell script. The definition of a typical test
looks like:
"fontconfig": {
"description": "Fontconfig”,
"type": "compile”,
"test": "unix/fontconfig”,
"pkg-config-args": "fontconfig freetype2”,
"libs": "-lfontconfig -lfreetype"
}
This basically defines a configure test for fontconfig. It’s a compile test,
the test being in config.tests/unix/fontconfig. It’ll try to use pig-config to
determine the correct LIBS and CFLAGS to compile and link against the library,
and there is a fallback for the libs in case fontconfig can’t be found.
Again, the type variable refers to a callback (qtConfTest_compile in this case).
After that we have the central section that defines all the features. Let’s
take one example:
"icu": {
"description": "ICU”,
"autoDetect": "!config.win32”,
"condition": "tests.icu”,
"output": [ "publicQtConfig” ]
},
This defines the icu feature. It’s not auto-detected on windows, requires the
ice configure test to pass, and will then generate one output called
publicQtConfig. Here are some details of the fields:
description: A short description of the feature. Used by the summary section
below
autoDetect: Should evaluate to a boolean value whether to automatically detect
the feature. Defaults to true
emitIf: Skip the feature completely if this evaluated to false (don’t evaluate
conditions or outputs). Defaults to true.
enable: Evaluates to a condition that will enable the feature (defaults to
“input.feature == yes”)
disable: the opposite, (defaults to “input.feature == no”)
condition: A condition that determines whether the feature is enabled/disabled.
Will generate an error if it conflicts with the enable field above
output: Different types of output to generate
Output deserves a separate section. Also here you can define arbitrary
callbacks, but the standard types should cover most needs:
“publicQtConfig": Add the feature name to the QT_CONFIG variable in the public
pri file (here qconfig.pri)
“publicConfig": Add the feature name to the CONFIG variable in the public pri
file (here qconfig.pri)
"privateConfig": Same for the private pri (qmodule.pri)
“feature”: Defines a feature. Adds it to QT_CONFIG if available, sets
QT_NO_FEATURE otherwise
{ “type”: “define”, “name”: “FOO”, “value”: “expression” }
#define FOO expression in the public header file, expression is
evaluated
{ “type”: “libs”, “test”: “configtest” }
Output QMAKE_LIBS/CFLAGS_FEATURE defining parameters required to use an
external library
An addition, there are varAssign, varAppend and varRemove to assign, append and
remove values from qmake variables
All outputs can have a ‘negative’: true/false field (default false), that would
reverse when output is being generated (usually only if the feature is
available, and a ‘condition’ field.
Finally there are two sections called ‘earlyReport’ and ‘report’. Use ‘report’
unless you know what you’re doing. These sections allow you to define
conditions under which notes, warnings or errors are being reported back to the
user.
Finally, there’s a summary section, that defines the configure summary we’re
reporting back to the user. I’ll leave figuring out the details here as an
exercise to the reader ;-)
Cheers,
Lars
_______________________________________________
Development mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/development