diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2016-10-25 13:59:59 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2016-10-28 14:17:06 +0000 |
commit | 7a8a21c03b8e49e7dbf0462d2c698e960bdacbb4 (patch) | |
tree | 8a0d04d8def98dc1be9d25f3959fbdddea3ba5a2 /doc | |
parent | ae1609b0c9f208a0b8d87a9e3c36399f70b30cbc (diff) |
Improve the documentation of the Rule item
We should make it easier for users to find out how to write their own
rules.
Task-number: QBS-880
Task-number: QBS-1012
Change-Id: I5469a5b17a4f1967db0dd4c281e5292124a2928c
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/reference/items/artifact.qdoc | 4 | ||||
-rw-r--r-- | doc/reference/items/rule.qdoc | 159 |
2 files changed, 102 insertions, 61 deletions
diff --git a/doc/reference/items/artifact.qdoc b/doc/reference/items/artifact.qdoc index 02ac2733b..09db7502e 100644 --- a/doc/reference/items/artifact.qdoc +++ b/doc/reference/items/artifact.qdoc @@ -40,6 +40,10 @@ \section1 Artifact Properties + \note The code on the right-hand side of these properties has access to the set of input + artifacts, that is, it can refer to the \c inputs map and, if the rule is not a multiplex rule, + the \c input variable. + \table \header \li Property diff --git a/doc/reference/items/rule.qdoc b/doc/reference/items/rule.qdoc index edebd26f4..f51b3f76b 100644 --- a/doc/reference/items/rule.qdoc +++ b/doc/reference/items/rule.qdoc @@ -34,22 +34,57 @@ \title Rule Item \brief Creates transformers for input tags. - A \e {multiplex rule} creates one \e transformer that takes all - input artifacts with the matching input file tag and creates - one or more artifacts (e.g. C++ linker). - A \e {simplex rule} creates one transformer per matching input file - (e.g. C++ compiler). - For instance, the following rule transforms text files: + In \QBS, rules create \e transformers that produce output files from input files. + The term \e transformer refers to a list of \l{Command and JavaScriptCommand}{commands}. + These commands are created in a rule's \e {prepare script}. They do the actual work, either + directly or by executing external commands. + + \section1 A Simple Example + + The following rule takes text files and replaces Windows-style line endings with their + Unix-style counterparts. We will look at it one piece at a time. + \code Rule { + multiplex: false + \endcode + A \e {multiplex rule} creates one transformer that takes all input artifacts with the + matching input file tag and creates one or more output artifacts. We are setting the + respective property to \c false here, indicating that we want to create one transformer + per input file. + \note This is actually the default, so the above assignment is not required. + \code inputs: ["txt_input"] + \endcode + Here we are specifying that our rule is interested in input files that have the tag + "txt_input". Such files could be source files, in which case you would tag them + using a \l{Group Item}{Group}. Or they could in turn get generated by a different rule, + in which case that rule would assign the file tag. + The files matching the tag will be available in the prepare script under the name + \c inputs (see \l{inputs and outputs}{The inputs and outputs Variables}). + \code Artifact { - filePath: "output.txt" - fileTags: "txt_output" + filePath: input.fileName + ".out" + fileTags: ["txt_output"] } + \endcode + Here we are specifying that for every input file, we want to create one output file + whose name is the same as the input file, but with an additional extension. Because we are + giving a relative path, \QBS will prepend that path by the product's build directory. + + In addition, we tell \QBS that the output files should get the file tag "txt_output". This + enables other rules to use these files as inputs. You must always assign suitable file tags + to your output artifacts, or the rule will not be run. + See \l{Rules and Product Types} for details. + + If you want to create more than one output file per input file, you simply provide multiple + \c Artifact items. The set of output artifacts will be available in the prepare script + under the name \c outputs (see \l{inputs and outputs}{The inputs and outputs Variables}). + + \code prepare: { var cmd = new JavaScriptCommand(); - cmd.description = "Processing '" + input.filePath + "'"; + cmd.description = input.fileName + "->" + output.fileName; cmd.highlight = "codegen"; cmd.sourceCode = function() { var file = new TextFile(input.filePath); @@ -60,64 +95,66 @@ file.write(content); file.close(); } - return cmd; + return [cmd]; } } \endcode - This example exhibits some interesting features of rules: - \list - \li If there is only one input file, the property \c input is available as syntactic sugar - for \c inputs[0]. - \li The filenames of the output artifacts are available as \c outputs. If there is only one - of these, it can be referred to it as \c output. - \endlist + The prepare script shown above puts everything together by creating the command that does + the actual transformation of the file contents, employing the help of the + \l{TextFile Service}{TextFile} class. - As a real-world example of a simplex rule, here is a simplified version - of \QBS' rule for transforming C++ sources into object files using gcc: - \code - import qbs.ModUtils - import qbs.Utilities - Rule { - id: compiler - inputs: ['cpp'] - auxiliaryInputs: ['hpp'] + As you can see, the return value is an array, meaning you can provide several commands to + implement the rule's functionality. For instance, if we had provided two \c Artifact items, + we might have also provided two commands, each of them creating one output file. - Artifact { - fileTags: ['obj'] - filePath: '.obj/' + Utilities.getHash(input.baseDir) + '/' + input.fileName + '.o' - } + For the \c input and \c output variables used in the code, see the next section. - prepare: { - var args = []; - if (product.moduleProperty('cpp', 'debugInformation')) - args.push('-g'); - var warnings = product.moduleProperty('cpp', 'warningLevel') - if (warnings === 'none') - args.push('-w'); - if (warnings === 'all') { - args.push('-Wall'); - args.push('-Wextra'); - } - if (product.moduleProperty('cpp', 'treatWarningsAsErrors')) - args.push('-Werror'); - var includePaths = product.moduleProperty('cpp', 'includePaths'); - for (i in includePaths) - args.push('-I' + includePaths[i]); - var defines = product.moduleProperty('cpp', 'defines'); - for (i in defines) - args.push('-D' + defines[i]); - args.push('-c'); - args.push(input.filePath); - args.push('-o'); - args.push(output.filePath); - var compilerPath = ModUtils.moduleProperty(product, 'compilerPath'); - var cmd = new Command(compilerPath, args); - cmd.description = 'compiling ' + input.fileName; - cmd.highlight = 'compiler'; - return cmd; - } - } - \endcode + \target inputs and outputs + \section1 The \c inputs and \c outputs Variables + + We already mentioned that the input and output artifacts are available in the prepare script + via the variables \c inputs and \c outputs, respectively. These variables are JavaScript + objects whose property keys are file tags and whose property values are lists of objects + representing the artifacts matching these tags. In our example, the \c inputs variable + has a single property \c txt_input, whose value is a list with one element. Similarly, the + \c outputs variable also has one single property \c txt_output, again with a list containing + one element. + + The actual artifact objects have the following properties: + \table + \header + \li Property + \li Description + \row + \li \c baseName + \li The file name without any extension. + \row + \li \c completeBaseName + \li The file name without the last extension. + \row + \li \c fileName + \li The name of the file (that is, \c filePath without any directory components). + \row + \li \c filePath + \li The full file path. + \row + \li \c fileTags + \li The list of the artifact's file tags. + \row + \li \c moduleProperty + \li A function taking two parameters. The first one is the name of a module, + the second one is the name of a property in that module. For instance, for an + artifact in a C++ product, a call to \c{moduleProperty("cpp", "defines")} returns the + list of defines that will be passed when compiling the respective file. + \endtable + + But what about the variables \c input and \c output that appeared in our example? These + are simply convenience variables which are available in the case that the \c inputs + and \c outputs variables contain only one artifact, respectively. So in our example, instead + of \c input we also could have written \c {inputs.txt_input[0]}, which is considerably + more verbose. + + \section1 Rules and Product Types It is important to know that when figuring out which rules to execute, \QBS starts at the product type and then looks for a way to produce artifacts with matching file tags from |