如变体感知匹配部分所述,属性为变体提供语义,并由 Gradle 的依赖管理引擎用来选择最佳匹配变体。
作为 Gradle 的用户,属性通常隐藏为实现细节。但了解Gradle 及其核心插件定义的标准属性可能会很有用。
作为插件作者,这些属性及其定义方式可以作为在生态系统插件中构建您自己的属性集的基础。
Gradle定义的标准属性
Gradle 定义了 Gradle 核心插件使用的标准属性列表。
独立于生态系统的标准属性
属性名称 | 描述 | 价值观 | 兼容性和消歧规则 |
---|---|---|---|
表示变体的主要目的 |
|
遵循生态系统语义(例如 |
|
表示该软件组件的类别 |
|
遵循生态系统语义(例如, |
|
|
|
遵循生态系统语义(例如,在 JVM 世界中, |
|
|
|
无默认,无兼容性 |
|
指示如何访问变体的依赖项。 |
|
遵循生态系统语义(例如,在 JVM 世界中, |
|
指示产生此输出的验证任务类型。 |
|
无默认,无兼容性 |
当 这些变体仅包含运行验证任务的结果,例如测试结果或代码覆盖率报告。它们不可发布,如果添加到已发布的组件中,将会产生错误。 |
属性名称 | 描述 | 价值观 | 兼容性和消歧规则 |
---|---|---|---|
|
组件级属性,派生的 |
基于状态方案,默认方案基于源存储库。 |
基于所使用的方案 |
JVM 生态系统特定属性
除了上面定义的生态系统独立属性之外,JVM 生态系统还添加了以下属性:
属性名称 | 描述 | 价值观 | 兼容性和消歧规则 |
---|---|---|---|
指示JVM版本兼容性。 |
整数使用 Java 1.4 及之前的版本 |
默认为 Gradle 使用的 JVM 版本,较低版本与较高版本兼容,优先选择最高兼容版本。 |
|
指示变体针对特定 JVM 环境进行了优化。 |
共同值为 |
如果有多个可用,该属性用于优先选择一种变体而不是另一种变体,但通常所有值都是兼容的。默认为 |
|
指示生成此输出的TestSuite的名称。 |
值是套件的名称。 |
无默认,无兼容性 |
|
指示生成此输出的TestSuiteTarget的名称。 |
值是目标的名称。 |
无默认,无兼容性 |
|
指示测试套件的类型(单元测试、集成测试、性能测试等) |
|
无默认,无兼容性 |
JVM 生态系统还包含许多针对不同属性的兼容性和消歧规则。愿意了解更多的读者可以看一下 的代码org.gradle.api.internal.artifacts.JavaEcosystemSupport
。
本地生态系统特定属性
除了上面定义的生态系统独立属性之外,原生生态系统还添加了以下属性:
属性名称 | 描述 | 价值观 | 兼容性和消歧规则 |
---|---|---|---|
指示二进制文件是否是使用调试符号构建的 |
布尔值 |
不适用 |
|
指示二进制文件是否是使用优化标志构建的 |
布尔值 |
不适用 |
|
指示二进制文件的目标架构 |
|
没有任何 |
|
指示二进制文件的目标操作系统 |
|
没有任何 |
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
。