[QBS] v2 of Proposal: improvements to the config system

Tom Sutcliffe devtomsci at me.com
Wed Mar 28 22:20:40 CEST 2012

For future reference, here is v2 of the proposal, updated with the consensus from Jörg/the list. I think everything here is pretty much agreed in principle, but any further feedback welcome of course!

The original proposal is here: http://lists.qt-project.org/pipermail/qbs/2012-March/000091.html
(although my webmail appears to have mangled its display in the archives, sorry about that!)

v2 follows:

1) Have the "qbs config" command-line use and display dot-separated properties just like the property syntax on the command-line and inside qbs files, rather than slashes.

For example instead of "qbs config defaults/platform" you'd say "qbs config defaults.platform". (Although as per (2) I propose that you'd set "modules.qbs.platform" instead).

I know internally config is implemented using QSettings which uses slashes but there's no real reason the user has to be concerned with that implementation detail. It would be simpler for the user to have only one syntax to remember. They can be mapped into QSettings-compatible slash-separated paths internally.

2) All properties should use the same fully-qualified name wherever they are accessed.

(Although in the qbs config namespace default module properties live under the modules.* group to avoid polluting the top-level namespace with module names)

So instead of having "defaults/platform" (in config), "platform" (on command line) and "qbs.platform" (when referred to in a .qbs file) there is one definitive name for the property, "qbs.platform". This can be overridden on the command-line with "qbs.platform:x86" (or, as currently, "platform:x86" for convenience). Another way of looking at this is that the config keyspace should mirror the module and property layout (albeit under a top-level group like "modules" or "profiles.<profileName>", of which see (3)). This has a few corollaries:

2a) Abolish (or deprecate) the "defaults" group in qbs config.

I think pretty much everything currently in the defaults group would move into the "modules.qbs" group, as they all map directly to properties in the qbs module. (Except for defaults/qtVersionName, see (3) for info on that).

TBC: there as a couple of other keys, "defaults/jobs" and "defaults/useColoredOutput", which don't belong in any module because they are of no relevance inside module context, and setting them from a profile makes no real sense. Current thinking is to move them to a "preferences" group, which is out of the way of projects (and not settable via profiles or command-line overrides which avoids confusion) but still accessible by the internals of qbs. If really necessary, qbs.configurationValue() would still allow access to such keys.

2b) Everything set in "qbs config" under the modules.* keyspace are automatically set as properties on the relevant module, as if every key in the config were specified on the commandline.

This would simplify .qbs files as they wouldn't need to worry about explicitly using qbs.configurationValue() to support config and thus it will be less places for bugs/typos to sneak in. Instead modules would just define properties and they would magically get set from the config in the same way as if they were specified manually on the command-line today. It would also mean that all properties could be specified in qbs config without qbs files having to explicitly support it.

2c) Properties in submodules should be referrable to using the syntax module.submodule.property even in .qbs files.

Remove the slightly messy workaround of using an id inside the Depends:
Depends { name: "qt.core" } // no "id:qtcore" needed
property var x: qt.core.version // Rather than qtcore.version or whatever

and on the command line:
qbs qt.core.version:4.7.2

3) Rework how the "qt" config group and qtcore module properties work.

The "qt" group in qbs config is a slightly special case because it doesn't map directly onto a module, and rather it defines a set of configurations for the qtcore module. So it's not possible to make use of the automatic propagation of config keys to module properties I proposed above. Instead we introduce a new concept "profiles" which is a generalisation of how the qt group works that can be applied to any properties not just those in the qt module. This means qtcore.qbs doesn't need to know anything about qbs.configurationValue() and the config path to read a setting is the same regardless of what Qt version you're using.

So from the point of view of the property namespace, qbs files would see:

qt.core.path: "D:\QtSDK-1.1\Desktop\Qt\4.7.2\mingw" // Or whatever
qt.core.binPath: // etc

The way we'd represent this in the QSettings keyspace would be something like this. I've modelled this on my setup where for a given qt version I need to set the architecture and platform at the same time - with this proposal these can be setup in exactly the same way.

profiles.myDefaultSetup.qt.core.path: "D:\QtSDK-1.1\Desktop\Qt\4.7.2\mingw"
profiles.myDefaultSetup.qbs.platform: "mingw32"
profiles.myDefaultSetup.qbs.architecture: "x86"

profiles.x64.qt.core.path: "D:\QtSDK-1.1\QtSources\4.7.2-msvc2010-x64"
profiles.x64.qbs.platform: "msvc2010"
profiles.x64.qbs.architecture: "x86_64"
profiles.x64.qbs.buildVariant: "release"

Which profile(s) are used is determined by the top-level "profile" key. Thus you could run "qbs build release profile:x64" (or just "qbs profile:x64") then all the keys under profiles.x64 would be set (ie qbs.platform would be set to "msvc2010" etc), or you could set the default value for this (and thus the default profile to be used) by calling "qbs config --global profile myDefaultSetup".

qbs profile:x64
would expand to (effectively)
qbs build release qt.core.path:D:\QtSDK-1.1\QtSources\4.7.2-msvc2010-x64 qbs.platform:msvc2010 qbs.architecture:x86_64

As before, properties in "qbs" can be specified on the command-line without prefix, so "platform:msvc2010" is equivalent to "qbs.platform:msvc2010". Multiple profiles to be enabled by using a comma separated format, eg: "profile:x64,somethingElse". If the same key is set in multiple profiles, the one specified last on the command line wins. In other words the final set of properties is built up sequentially by applying the following in order:

    1) values set in the *.qbs files themselves
    2) any default values in the modules.* config
    3) the specified platform
    4) any profiles, in the order they are specified on the command-line
    5) any values explicitly passed in on the command-line

4) qbs should support a mode whereby all the calculated properties are dumped out.

To aid debugging, qbs should support a mode where it dumps out the complete tree of calculated properties, taking into account the global and local config, command line args, profiles, and the evaluations from the .qbs files themselves including additions to cpp.defines from Modules etc. In other words the full state from just before the build starts. For example:

D:\myproj> qbs properties release profile:x64
Project myProj.qbp:
    Product myProj.exe
        qbs.platform: "msvc2010"
        qbs.architecture: "x86_64"
        qbs.buildVariant: "release"
        cpp.defines: ["UNICODE", "QT_GUI_LIB", "MY_PRODUCT_MACRO"]
        cpp.includePaths: [...]
        qt.core.path: "D:\QtSDK-1.1\QtSources\4.7.2-msvc2010-x64"
        qt.core.binPath: "D:\QtSDK-1.1\QtSources\4.7.2-msvc2010-x64/bin"
    myProperty: ... // Project property

5) platforms should be moved out of their separate ini files and into the global config.

This simplifies the number of places qbs stores state, and makes it easier to see what is going on. For example my setup (assuming the rest of the proposal is also implemented) would look like:

    >qbs config --list --global
    global variables:
    modules.qt.core.version: 4.7.2

    platforms.mingw32.qbs.targetOS: windows
    platforms.mingw32.qbs.toolchain: mingw
    platforms.mingw32.cpp.toolchainInstallPath: D:\QtSDK-1.1\mingw\bin

    platforms.msvc2010.qbs.targetOS: windows
    platforms.msvc2010.qbs.toolchain: msvc
    platforms.msvc2010.cpp.toolchainInstallPath: C:\Program Files (x86)\Microsoft Visual Studio 10.0
    platforms.msvc2010.cpp.windowsSDKPath: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A

    profile: mingw
    profiles.mingw.qbs.architecture: x86
    profiles.mingw.qbs.platform: mingw32
    profiles.mingw.qt.core.path: D:\QtSDK-1.1\Desktop\Qt\4.7.2\mingw

    profiles.x64.qbs.architecture: x86_64
    profiles.x64.qbs.platform: msvc2010
    profiles.x64.qt.core.path: D:\QtSDK-1.1\QtSources\4.7.2-msvc2010-x64
6) qbs global config should support import and export commands.

To facilitate bulk changes of config on platforms (like windows) where qbs's QSettings location is not easily accessible (because it's in the registry) there needs to be a way of editing the whole config from a text editor, which is most easily and most flexibly supported by having import and export commands:

    >qbs config --export configdump.txt
    >qbs config --import configdump.txt


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/qbs/attachments/20120328/62383e1b/attachment.html>

More information about the Qbs mailing list