Gradle 对 Maven POM 配置文件的支持

目录

引言

Maven 配置文件 能够在特定条件下自定义构建时元数据,例如在设置了特定系统属性时。一个典型的用例是为不同的运行时环境(如 Linux 与 Windows)应用特定的配置。例如,正在构建的项目可能在这些不同的平台上需要不同的依赖项。

在 Gradle 项目中实现构建时配置文件 #

如果仔细想想,Maven 配置文件本质上就是有限的 if 语句。Gradle 不需要为此提供特殊的构造。这是为什么呢?Gradle 使用编程语言,而不是 XML,来定义构建模型。这使您能够使用编程语言提供的完整表达能力来定义配置特定部分的条件。Gradle 的模型更丰富、更灵活,能够更精细地表达 Maven 配置文件通常用于的事情。一个非常简单且广泛使用的模式是将条件逻辑拆分到不同的脚本插件中,以使条件构建逻辑尽可能模块化和易于维护。以下代码片段演示了这种实现方式

if (project.hasProperty('env') && project.getProperty('env') == 'prod') {
    apply from: 'gradle/production.gradle'
} else {
    apply from: 'gradle/development.gradle'
}

上述方法允许根据您需要的任何情况对不同配置进行即时表达。这类似于 Maven 配置文件方法,但更简洁、更灵活。

用于表达变体的条件配置的另一种方法是使变体成为一等公民。Android 和 C/C++ Gradle 插件采用了这种方法。这表明 Gradle 团队认为在大多数情况下,这是一种更好的方法:使构建定义中的变体成为一等公民,而不是通过条件来表达。这种“变体即一等公民”的方法正在被添加到 JVM 插件中,以适应 JDK 兼容性等变体,并已深度集成到 Gradle 的依赖管理引擎中。

使用依赖于配置文件的 Maven 依赖项 #

我们已经讨论了 Maven 配置文件在配置构建中的作用以及 Gradle 中的替代方法。由于 Gradle 支持依赖于 POM 的构件,因此我们还必须考虑 Maven 配置文件如何影响依赖解析。

一些已发布的 Maven 构件,尤其是在公共 Maven Central 仓库中的,在依赖解析过程中依赖于其 POM 配置文件中声明的信息。这种做法被认为是一种应该避免的“反模式”,因为它会影响构建的可重现性。尽管如此,这在实践中仍然被使用,并且 Gradle 1.12 引入了对某些影响依赖解析的配置文件使用的支持。

Gradle 中支持的配置文件标准 #

Gradle 考虑了两个激活标准

  1. 默认激活的配置文件(Gradle 1.12 及更高版本可用)
  2. 在系统属性缺失时激活的配置文件(Gradle 2.0 及更高版本可用)

让我们看一些演示这两种用例的示例。

默认激活的配置文件 #

配置文件可以被认为是默认激活的。此行为由 activeByDefault 激活元素控制。让我们看一个已发布 POM 文件中包含的配置文件部分

<project>
    ...
    <profiles>
        <profile>
            <id>profile-1</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <dependencies>
                <dependency>
                    <groupId>org.apache.commons</groupId>
                    <artifactId>commons-lang3</artifactId>
                    <version>3.3.2</version>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
</project>

我们可以看到 activeByDefault 元素设置为 true。在 Gradle 解析相应的构件时,名为 profile-1 的配置文件将变得激活。此配置文件将 org.apache.commons:commons-lang3:3.3.2 依赖项声明为传递性依赖。反过来,Gradle 也会负责解析此依赖项。

在系统属性缺失时激活的配置文件 #

另一种 activeByDefault 的替代方法是通过特定系统属性的缺失来触发配置文件的激活。让我们看另一个使用此类型配置文件激活的 POM 文件

<project>
    ...
    <profiles>
        <profile>
            <id>profile-2</id>
            <property>
                <name>!env.type</name>
            </property>
        </profile>
    </profiles>
</project>

每当 env.type 系统属性定义时,此 POM 文件将激活名为 profile-2 的配置文件。

用于依赖解析的配置文件的替代方法 #

我们已经看到 Maven 配置文件如何用于表达构建配置中的变体,以及当 Gradle 消费使用配置文件作为其运行时定义一部分的 Maven 构件时,这对 Gradle 依赖解析有何影响。我们还看到下一代 Gradle 插件(Android、C/C++)如何通过使变体成为一等公民来采取不同的方法,并且这个概念也正在进入 Gradle 对通用 JVM 语言的支持。这同样对依赖解析有深远影响,就像 Maven 配置文件影响依赖解析一样。

使变体成为构建模型中的一等公民的一个显著好处是,这些信息可以被用来提供支持变体的依赖解析。例如,在为 x86 架构构建带有调试符号的二进制文件时,应该使用已声明依赖项的 x86 变体,并且最好是包含调试符号的变体(如果可用)。这将自动强制执行整个传递性依赖图。在软件构建和依赖管理中存在无数的变体情况。

Gradle 创始人兼 Gradle Inc. CEO Hans Dockter 最近发布了 2014 Gradle 路线图,其中您可以看到“支持变体的依赖管理”是当前正在进行的一项关键工作。预计在未来一年内,Gradle 在这一领域将推出新的功能。

讨论