Uploaded image for project: 'Qbs ("Cubes")'
  1. Qbs ("Cubes")
  2. QBS-585

make it possible to parameterize dependencies

    XMLWordPrintable

Details

    • 1dd00091f99e62d8c10677de98e753fe332565a9

    Description

      not all dependencies need to be actually linked into the Product:

      • a module may be needed at runtime only
        • applications/tools
        • generic libraries (in qt: opengl, openssl, ...)
        • plugins (including qml modules)
      • such dependencies would be forwarded to Exports (see QBS-584), to make sure exported Rules (see QBS-583) are not executed too early
      • such dependencies would be also used for deployment
      • as a special variation, a library may be loaded only at runtime, but its include path needs to be added to the compiler call

      a dependency can be principally parametrized from four locations:

      • the hard-coded default behavior of the Rules
      • said behavior may depend on a Parameter. that parameter may be set in several places:
        • in Products which Export Modules, and by extension in Modules themselves. i.e., the imported Module requests how it shall be used (by default).
        • in Depends items which import Modules. i.e., the importing Product explicitly specifies how the imported Module shall be used (overrides default)
        • in DefaultParameters items which override the imported Modules' defaults in the importing Products' scope, and can be still overridden by the Depends items.
          • these items shall have an optional productTypes property which limits to which imported Modules these parameters should apply, e.g. only plugins.

      first declare the parameter itself:

      cpp.qbs
      Module {
          name: "cpp"
          // parameters are just specially scoped property declarations.
          // the syntax is consistent with Constraints (see QBS-995), and shares the namespace with them.
          Parameter {
              // no default value, because it is different for each product type.
              // so let the Rules decide themselves.
              property bool link
          }
          Parameter {
              property bool wholeArchive: false
          }
          Parameter {
              property bool useHeaders: true
          }
      }
      

      then create a Module which sets a default for a parameter:

      Plugin.qbs
      Product {
          productTypes: [ "plugin", cpp.static ? "staticLibrary" : "dynamicLibrary" ]
          Depends {
              name: "cpp"
          }
          cpp.static: false
          Export {
              Parameters {
                  cpp.link: cpp.static
              }
          }
      }
      
      MyPlugin1.qbs
      Plugin {
          name: "myPlugin1"
          // inherits the default parameter value from Plugin
      }
      

      this results in an exported Module:

      exported/MyPlugin1.qbs
      Module {
          name: "myPlugin1"
          Parameters {
              cpp.link: false
          }
          ...
      }
      
      MyPlugin2.qbs
      Plugin {
          name: "myPlugin2"
          Export {
              Parameters {
                  cpp.link: true  // i'm a funny plugin, i want to be linked always
              }
          }
      }
      

      then use the parameter in different ways:

      MyApp1.qbs
      Product {
          Depends {
              // not linked
              name: "myPlugin1"
          }
          Depends {
              // linked
              name: "myPlugin2"
          }
          Depends {
              name: "OpenSSL"
              // we don't want to link it, and we have our own function prototypes
              // (openssl is unable to keep binary compat anyway)
              cpp.useHeaders: false
              cpp.link: false
          }
          Depends {
              name: "OpenGL"
              // we don't want to link it, but we want to use its headers for compilation
              cpp.link: false
          }
      }
      
      MyApp2.qbs
      Product {
          DefaultParameters {
              productTypes: ["plugin"]
              cpp.link: true
          }
          Depends {
              // linked
              name: "myPlugin1"
          }
      }
      

      also, static plugins need to be actually linked. this will typically also require auto-generating static initializers for the plugins' factory methods. this is framework-dependent, so it would end up in a QtPlugin item.

      Attachments

        Issue Links

          For Gerrit Dashboard: QBS-585
          # Subject Branch Project Status CR V

          Activity

            People

              jbornema Joerg Bornemann
              buddenha Oswald Buddenhagen
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes