aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2016-10-25 13:59:59 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2016-10-28 14:17:06 +0000
commit7a8a21c03b8e49e7dbf0462d2c698e960bdacbb4 (patch)
tree8a0d04d8def98dc1be9d25f3959fbdddea3ba5a2
parentae1609b0c9f208a0b8d87a9e3c36399f70b30cbc (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>
-rw-r--r--doc/reference/items/artifact.qdoc4
-rw-r--r--doc/reference/items/rule.qdoc159
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