规则

为输入标签创建转换器。 更多信息...

属性

详细描述

在 Qbs 中,规则创建用于从输入文件生成输出文件的 转换器。术语 转换器 指的是一系列 命令。这些命令在一个规则的 准备 脚本中创建。它们执行实际工作,或者直接执行,或者通过执行外部命令。

简单示例

以下规则将文本文件从以 Windows 风格的行结束符更改为 Unix 风格的对应项。我们将逐一查看它。

    Rule {
        multiplex: false

一个 复用规则 创建一个转换器,它从所有匹配的输入文件标签的输入项目生成一个或多个输出项目。我们在这里将各自的属性设置为 false,表示我们想要为每个输入文件创建一个转换器。

注意:这实际上是默认设置,所以上面的赋值不是必需的。

        inputs: ["txt_input"]

这里我们指定我们的规则对具有标签 "txt_input" 的输入文件感兴趣。这样的文件可以是源文件;在这种情况下,您将使用 标记它们。或者它们可以由不同的规则生成,在这种情况下,该规则将分配文件标签。匹配该标签的文件将在 准备 脚本中以 inputs 的名称提供(请参阅 输入和输出变量)。

        Artifact {
            filePath: input.fileName + ".out"
            fileTags: ["txt_output"]
        }

在此,我们指定对于每个输入文件,我们要创建一个输出文件,其名称与输入文件相同,但需要添加一个扩展名。因为我们提供了一个相对路径,Qbs 将在这个路径之前添加产品的构建目录。

此外,我们通知 Qbs,输出文件应获取文件标记 "txt_output"。这使其他规则可以使用这些文件作为输入。您必须始终为您的输出工件分配合适的文件标记,否则规则将不会运行。有关详细信息,请参阅 规则和产品类型

如果您想为每个输入文件创建多个输出文件,您只需提供多个 工件 项。输出工件集将在准备脚本中命名为 outputs(参见 输入和输出变量)。

        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "generating" + output.fileName + " from " + input.fileName;
            cmd.highlight = "codegen";
            cmd.sourceCode = function() {
                var file = new TextFile(input.filePath);
                var content = file.readAll();
                file.close()
                content = content.toUpperCase();
                file = new TextFile(output.filePath, TextFile.WriteOnly);
                file.write(content);
                file.close();
            }
            return [cmd];
        }
    }

上面的准备脚本通过创建实际转换文件内容的命令将一切组合起来,利用了 TextFile 类的帮助。

如您所见,返回值是一个数组,这意味着您可以提供多个命令以实现规则的实用性。例如,如果我们提供了两个 Artifact 项,我们也可能提供两个命令,每个命令创建一个输出文件。

有关代码中使用的 inputoutput 变量,请参阅下一节。

输入和输出变量

我们已提到输入和输出工件可以通过 inputsoutputs 变量分别在准备脚本中获取。这些变量是 JavaScript 对象,其属性键是文件标记,其属性值是表示匹配这些标记的工件的对象的列表。在我们的示例中,inputs 变量有一个单一的属性 txt_input,其值是一个只有一个元素的列表。同样,outputs 变量也有一个单一的属性 txt_output,同样是一个只包含一个元素的列表。

实际的工件对象具有以下属性

属性描述
baseName没有扩展名的文件名。
completeBaseName没有最后一个扩展名的文件名。
fileName文件名(即没有目录组件的 filePath)。
filePath完整的文件路径。
fileTags工件文件标记的列表。

工件对象包含每个在产品中使用的模块的属性。这可以用来访问模块的属性。例如,对于 C++ 产品中的工件,artifact.cpp.defines 是在编译相应文件时传递的 define 列表。

但我们的例子中出现的变量 inputoutput 怎么样?这些变量仅仅是提供便利的变量,在 inputsoutputs 变量只包含一个工件时可用。因此,在我们的例子中,我们也可以用 inputs.txt_input[0] 替代 input,这会更冗长。

规则和产品类型

了解Qbs在选择要执行的规则时的处理过程非常重要。Qbs从产品类型开始,然后寻找从源文件生成具有匹配文件标签的工件的方法。它是通过各自的输入和输出标签相互连接的规则链来实现的。例如,考虑以下简单的C++项目

Product {
    type: ["application"]
    Depends { name: "cpp" }
    files: ["main.cpp"]
}

以下是构建此产品的方式

  1. Qbs寻找一个可以生成具有文件标签"application"的规则。此类规则在cpp模块中找到(即调用链接器的规则)。
  2. 由于前一步中找到的规则接受"obj"类型的输入,因此Qbs现在寻找生成该类型工件的规则。同样,此类规则也位于cpp模块中(运行编译器的规则)。
  3. 前一步中找到的规则接受"cpp"类型的输入。没有找到创建此类工件的规则,但我们有一个具有匹配类型的源文件(因为cpp模块包含一个FileTagger,它将此类型附加到"main.cpp"上,因为其文件扩展名)。
  4. 现在有一系列规则链接从源文件标签到产品类型,这些规则的命令随后依次执行,直到我们得到可执行文件。

完整示例

以下代码片段展示了Product内部的单个Rule,并总结了前面的部分。

注意:将产品类型设置为"txt_output"文件标签,以告诉Qbs该产品依赖于由自定义规则生成的输出工件。否则,则不会执行该规则。

import qbs.TextFile

Product {
    type: "txt_output"

    Group {
        name: "lorem_ipsum"
        files: "lorem_ipsum.txt"
        fileTags: "txt_input"
    }

    Rule {
        multiplex: false
        inputs: ["txt_input"]
        Artifact {
            filePath: input.fileName + ".out"
            fileTags: ["txt_output"]
        }
        prepare: {
            var cmd = new JavaScriptCommand();
            cmd.description = "generating" + output.fileName + " from " + input.fileName;
            cmd.highlight = "codegen";
            cmd.sourceCode = function() {
                var file = new TextFile(input.filePath);
                var content = file.readAll();
                file.close()
                content = content.toUpperCase();
                file = new TextFile(output.filePath, TextFile.WriteOnly);
                file.write(content);
                file.close();
            }
            return [cmd];
        }
    }
}

属性文档

alwaysRun : bool

如果设置为true,则规则的命令将始终执行,即使所有输出工件都已是最新的。

默认值:false


auxiliaryInputs : stringList

一个文件标签列表。此规则将与生成与该属性值兼容的工件的每个其他规则相关联。

inputs不同,这个属性对prepare脚本中inputs变量的内容没有影响。

考虑当前产品中所有规则以及产品依赖项中生成目标工件的规则。

默认值:未定义


condition : bool

如果设置为true,则启用规则,否则什么也不做。

默认值:true


[since Qbs 1.12] excludedInputs : stringList

一个文件标签列表。防止连接到生成这些文件标签的规则。

默认值:未定义

此属性是在Qbs 1.12中引入的。


explicitlyDependsOn : stringList

一个文件标签列表。将匹配文件标签的每个工件添加到每个输出节点的依赖项中。考虑当前产品中所有工件。

默认值:未定义


[since Qbs 1.12] explicitlyDependsOnFromDependencies : stringList

一个文件标签列表。将匹配文件标签的每个工件添加到每个输出节点的依赖项中。仅考虑依赖于当前产品的产品的目标工件。

默认值:未定义

此属性是在Qbs 1.12中引入的。


inputs : stringList

一个文件标签列表,输入工件必须匹配这些标签。

所有输出工具将依赖于具有给定输入文件标签的产品中所有工具。此外,这些工具在inputs变量中的 prepare 脚本中也可以使用。

默认值:未定义


inputsFromDependencies : stringList

必须匹配产品依赖项工具的文件标签列表。

例如,当前产品中产品 foo 可能如下所示

Depends {
    name: "foo"
}

所有与给定文件标签匹配的 foo 工具都将在 inputs 变量中的 prepare 脚本中出现。

默认值:未定义


multiplex : bool

确定这是否是一个多路复用规则。

默认值:false


outputArtifacts : var

作为JavaScript对象指定的输出工具数组。

例如

outputArtifacts: [{
    filePath: "myfile.cpp",
    fileTags: ["cpp"],
    cpp: { cxxLanguageVersion: "c++11" }
}]

有关可能的属性描述,请参阅Artifact项的文档。

输出工具可以通过此属性或通过Artifact项指定。如果输出集不是固定的而是依赖于输入的内容,请使用此属性。如果没有提供文件标签,Qbs将应用当前上下文中已知的所有文件标签器到输出文件名。

用户可以在工具对象上设置属性explicitlyDependsOn,这与Rule.explicitlyDependsOn类似。

默认值:未定义


outputFileTags : stringList

如果通过outputArtifacts指定输出工具,则此属性必须指定规则可能生成的文件标签列表。

默认值:未定义


prepare : script

一个脚本,用于准备将输入转换成输出的命令。

此脚本中的代码被视为一个具有签名function(project, product, inputs, outputs, input, output, explicitlyDependsOn)的函数。

如果此规则有多个输入工具,则参数inputundefined。同样,如果正好有一个输出工具,则只定义了output

默认值:未定义


requiresInputs : bool

指定即使没有可用的输入工具,也应创建规则命令。

如果不确定输入文件是否存在,但希望Qbs在这些文件不存在的情况下创建输出文件,则启用此属性可能有用。

如果规则声明了任何输入,设置为true,否则为false


©2023 Qt公司版权所有。本文件中包含的文档贡献是各自所有权者的版权。本文件中提供的文档根据自由软件基金会发布的GNU自由文档许可证版本1.3许可。