Gradle 定义的标准属性
Gradle 定义了一系列由 Gradle 的核心插件使用的标准属性。
与生态系统无关的标准属性
属性名称 | 描述 | 值 | 兼容性和消除歧义规则 |
---|---|---|---|
指示变体的主要用途 |
|
遵循生态系统语义(例如, |
|
指示此软件组件的类别 |
|
遵循生态系统语义(例如, |
|
指示 |
|
遵循生态系统语义(例如,在 JVM 世界中, |
|
指示 |
|
没有默认值,没有兼容性 |
|
指示如何访问变体的依赖项。 |
|
遵循生态系统语义(例如,在 JVM 世界中, |
|
指示哪种验证任务生成了此输出。 |
|
没有默认值,没有兼容性 |
当 这些变体旨在仅包含运行验证任务的结果,例如测试结果或代码覆盖率报告。它们**不可发布**,如果添加到已发布的组件中,将产生错误。 |
属性名称 | 描述 | 值 | 兼容性和消除歧义规则 |
---|---|---|---|
|
组件级别属性,派生 |
基于 状态方案,默认方案基于源代码库。 |
基于正在使用的方案 |
JVM 生态系统特定属性
除了上面定义的生态系统独立属性之外,JVM 生态系统还添加了以下属性
属性名称 | 描述 | 值 | 兼容性和消除歧义规则 |
---|---|---|---|
指示 JVM 版本兼容性。 |
对于 Java 1.4 及之前版本,使用 |
默认为 Gradle 使用的 JVM 版本,较低版本与较高版本兼容,优先选择最高兼容版本。 |
|
指示变体是否针对特定 JVM 环境进行了优化。 |
常见值包括 |
如果有多个变体可用,则使用此属性来优先选择一个变体,但通常所有值都是兼容的。默认值为 |
|
指示生成此输出的 TestSuite 的名称。 |
值为 Suite 的名称。 |
没有默认值,没有兼容性 |
|
指示生成此输出的 TestSuiteTarget 的名称。 |
值为 Target 的名称。 |
没有默认值,没有兼容性 |
|
指示测试套件的类型(单元测试、集成测试、性能测试等)。 |
|
没有默认值,没有兼容性 |
JVM 生态系统还包含一些针对不同属性的兼容性和消除歧义规则。想要了解更多信息的读者可以查看 org.gradle.api.internal.artifacts.JavaEcosystemSupport
的代码。
原生生态系统特定属性
除了上面定义的生态系统独立属性之外,原生生态系统还添加了以下属性
属性名称 | 描述 | 值 | 兼容性和消除歧义规则 |
---|---|---|---|
指示二进制文件是否使用调试符号构建 |
布尔值 |
N/A |
|
指示二进制文件是否使用优化标志构建 |
布尔值 |
N/A |
|
指示二进制文件的目标架构 |
|
无 |
|
指示二进制文件的目标操作系统。 |
|
无 |
Gradle 插件生态系统特定属性
对于 Gradle 插件开发,从 Gradle 7.0 开始支持以下属性。Gradle 插件变体可以通过此属性指定与 Gradle API 版本的兼容性。
属性名称 | 描述 | 值 | 兼容性和消除歧义规则 |
---|---|---|---|
指示 Gradle API 版本兼容性。 |
有效的 Gradle 版本字符串。 |
默认为当前运行的 Gradle,较低的版本与较高的版本兼容,优先选择最高兼容版本。 |
在构建脚本或插件中创建属性
属性是类型化的。可以通过 Attribute<T>.of
方法创建属性。
// An attribute of type `String`
val myAttribute = Attribute.of("my.attribute.name", String::class.java)
// An attribute of type `Usage`
val myUsage = Attribute.of("my.usage.attribute", Usage::class.java)
// An attribute of type `String`
def myAttribute = Attribute.of("my.attribute.name", String)
// An attribute of type `Usage`
def myUsage = Attribute.of("my.usage.attribute", Usage)
属性类型支持大多数 Java 基本类;例如 String
和 Integer
;或任何扩展 org.gradle.api.Named
的类。属性必须在 dependencies
处理程序上的属性模式中声明。
dependencies.attributesSchema {
// registers this attribute to the attributes schema
attribute(myAttribute)
attribute(myUsage)
}
dependencies.attributesSchema {
// registers this attribute to the attributes schema
attribute(myAttribute)
attribute(myUsage)
}
然后可以配置配置以设置属性的值。
configurations {
create("myConfiguration") {
attributes {
attribute(myAttribute, "my-value")
}
}
}
configurations {
myConfiguration {
attributes {
attribute(myAttribute, 'my-value')
}
}
}
对于类型扩展 Named
的属性,属性的值**必须**通过对象工厂创建。
configurations {
"myConfiguration" {
attributes {
attribute(myUsage, project.objects.named(Usage::class.java, "my-value"))
}
}
}
configurations {
myConfiguration {
attributes {
attribute(myUsage, project.objects.named(Usage, 'my-value'))
}
}
}
属性匹配
属性兼容性规则
属性允许引擎选择兼容的变体。在某些情况下,生产者可能没有完全满足消费者要求的内容,但可能有一个可以使用的变体。
例如,如果消费者要求库的 API,而生产者没有完全匹配的变体,则可以考虑运行时变体兼容。这在发布到外部存储库的库中很常见。在这种情况下,我们知道即使没有完全匹配(API),我们仍然可以针对运行时变体进行编译(它包含更多我们编译所需的内容,但仍然可以使用)。
Gradle 提供了 属性兼容性规则,可以为每个属性定义这些规则。兼容性规则的作用是解释哪些属性值根据消费者的要求是兼容的。
属性消歧规则
由于一个属性可以有多个值是兼容的,因此 Gradle 需要在所有兼容的候选者中选择“最佳”候选者。这称为“消歧”。
这是通过实现 属性消歧规则 来完成的。
属性消歧规则必须通过 属性匹配策略 注册,您可以从 属性模式 中获取该策略,它是 DependencyHandler 的成员。
变体属性匹配算法
当一个组件有多个不同的变体,并且每个变体有多个不同的属性时,找到最佳变体可能会变得很复杂。Gradle 的依赖解析引擎在寻找最佳结果(或失败)时执行以下算法。
-
每个候选者的属性值都会与消费者的请求属性值进行比较。如果候选者的值与消费者的值完全匹配,通过了属性的兼容性规则,或者没有提供,则该候选者被认为是兼容的。
-
如果只有一个候选者被认为是兼容的,那么该候选者获胜。
-
如果多个候选者是兼容的,但其中一个候选者与其他候选者匹配所有相同的属性,Gradle 会选择该候选者。这是具有“最长”匹配的候选者。
-
如果多个候选者是兼容的,并且与相同数量的属性兼容,Gradle 需要对候选者进行消歧。
-
对于每个请求的属性,如果候选者没有与消歧规则匹配的值,则将其从考虑范围中排除。
-
如果属性具有已知的优先级,Gradle 将在只有一个候选者剩余时停止。
-
如果属性没有已知的优先级,Gradle 必须考虑所有属性。
-
-
如果仍然存在多个候选者,Gradle 将开始考虑“额外”属性来对多个候选者进行消歧。额外属性是消费者没有请求但至少在一个候选者上存在的属性。这些额外属性按优先级顺序考虑。
-
如果属性具有已知的优先级,Gradle 将在只有一个候选者剩余时停止。
-
在考虑了所有具有优先级的额外属性之后,如果剩余的候选者与所有非排序的消歧规则兼容,则可以选择它们。
-
-
如果仍然存在多个候选者,Gradle 将再次考虑额外属性。如果候选者具有最少的额外属性数量,则可以选择它。
如果在任何步骤中都没有候选者保持兼容,则解析失败。此外,Gradle 会输出从步骤 1 开始的所有兼容候选者的列表,以帮助调试变体匹配失败。
插件和生态系统可以通过实现兼容性规则、消歧规则以及告诉 Gradle 属性的优先级来影响选择算法。具有更高优先级的属性用于按顺序消除兼容的匹配项。
例如,在 Java 生态系统中,org.gradle.usage
属性的优先级高于 org.gradle.libraryelements
。这意味着,如果两个候选者都具有对 org.gradle.usage
和 org.gradle.libraryelements
的兼容值,Gradle 将选择通过 org.gradle.usage
的消歧规则的候选者。