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
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development

Reply via email to