[Qbs] Property from parent overridden instead of concatenated

Christian Kandeler christian.kandeler at qt.io
Mon Jul 2 16:01:06 CEST 2018

On Mon, 2 Jul 2018 15:42:43 +0200
<resurrection at centrum.cz> wrote:

> I remember seeing something about this but I wanted to know if this is a WAD or bug. Consider:
> //imports/MyProduct.qbs
> Product {
>     Depends { name: "cpp" }
>     cpp.defines: ["MY_DEF"]
> }
> //SomeProject.qbs
> MyProduct {
>     cpp.defines: ["ANOTHER_DEF"]
> }
> What will be the value of `cpp.defines`? To me quite unexpectedly only "ANOTHER_DEF". 

Yes, that's right. I suppose the rationale was that explicitly removing stuff is more complicated, so overwrite is the default. Whether that was the correct decision is debatable; there is something to be said for auto-inheriting. Similarly for properties set in groups vs the value in the surrounding product.

> In order to have both values I would need to do this:
> MyProduct {
>     Properties {
>         condition: true
>         cpp.defines: [String(outer), "ANOTHER_DEF"]

Good lord, no:
MyProduct {
    cpp.defines: base.concat("ANOTHER_DEF")
See https://doc.qt.io/qbs/qml-qbslanguageitems-module.html#base

> That is pretty weird to me. First of all the fact that unlike elsewhere (e.g. from a Module) inherited properties are overriden. 

Actually, property assignments in modules are the *only* ones that accumulate. In particular, inheritance never accumulates, anywhere.

> But even more the fact that "outer" is neither list/array nor string. It needs to be explicitely converted to String to satisfy some kind of condition that forces all cpp.defines to be of type String even if they are actually convertible to it.

The behavior is entirely correct. cpp.defines is of type string list, so trying to put it into a string list is incorrect, as the resulting type would be a list of list of strings. It does not matter that the value is convertible to string -- almost everything is in JavaScript. Such automatic conversions are exactly what the type system is supposed to prevent. See also https://codereview.qt-project.org/#/c/169577/.
(You would use outer.concat() instead, but see above for the real solution here.)


More information about the Qbs mailing list