什么是 Gradle

[toc]

概述

Gradle是一个开源的构建自动化工具,它被设计得足够灵活,可以构建几乎任何类型的软件。以下是它最重要的一些特性的高级概述:

  • 高性能
    Gradle仅避免不必要的工作,仅运行需要运行的任务,因为它们的输入或输出已更改。您还可以使用构建缓存来启用以前运行的任务输出或甚至来自其他计算机(具有共享构建缓存)。
    Gradle还实现了许多其他的优化,开发团队也在不断改进Gradle的性能。

  • JVM 底层
    Gradle运行在JVM上,必须安装Java开发工具包(JDK)才能使用它。对于熟悉Java平台的用户来说,这是一个额外的好处,因为您可以在构建逻辑中使用标准的Java api,比如自定义任务类型和插件。它也使得在不同的平台上运行Gradle变得很容易。
    请注意,Gradle不仅仅局限于构建JVM项目,它甚至打包了对构建本地项目的支持。

  • 约定
    Gradle借鉴了Maven的经验,通过实现约定使常见类型的项目(如Java项目)易于构建。应用适当的插件,您可以很容易地为许多项目提供精简的构建脚本。但是这些约定并没有限制你:Gradle允许你覆盖它们,添加你自己的任务,并对基于约定的构建进行许多其他定制。

  • 扩展性
    你可以很容易地扩展Gradle来提供你自己的任务类型,甚至构建模型。它添加了许多新的构建概念,比如样式和构建类型。

  • IDE 支持
    有几个主要的ide允许你导入Gradle构建并与之交互:Android Studio、IntelliJ IDEA、Eclipse和NetBeans。Gradle还支持生成将项目加载到Visual Studio所需的解决方案文件。

  • 洞察
    Build Scans提供有关可以用于标识构建问题的构建运行的广泛信息。它们特别擅长帮助您识别构建性能的问题。您还可以与其他人共享Build Scans,如果您需要询问建议时需要提出建议,这尤其有用。

关于Gradle你需要知道的五件事

Gradle是一个灵活而强大的构建工具,当你第一次开始使用它时,你会很容易感到害怕。然而,理解下面的核心原则会让Gradle变得更容易接近,你会在不知不觉中熟练使用这个工具。

1.Gradle是一个通用的构建工具

Gradle允许你构建任何软件,因为它很少假设你要构建什么或者应该怎么做。最显著的限制是依赖项管理目前只支持Maven和ivy兼容的存储库和文件系统。

这并不意味着您必须做大量的工作来创建一个构建。通过添加一层约定和通过插件预构建的功能,Gradle使得构建常见类型的项目(比如Java库)变得很容易。你甚至可以创建和发布自定义插件来封装你自己的约定和构建功能。

2.核心模型是基于任务的

Gradle将其构建建模为任务(工作单元)的有向无环图(dag)。这意味着构建本质上配置了一组任务,并根据它们的依赖关系将它们连接在一起,从而创建DAG。一旦创建了任务图,Gradle就会确定哪些任务需要按照哪些顺序运行,然后继续执行它们。

任务本身包括:

  • Actions — 做一些事情的工作,如复制文件或编译源代码
  • Inputs — Actions 使用或操作的值、文件和目录
  • Outputs — Actions 修改或生成的文件和目录

事实上,根据任务需要做的事情,上面所有这些都是可选的。有些任务——比如标准的生命周期任务——甚至没有任何动作。它们只是为了方便而将多个任务聚合在一起。

您可以选择要运行的任务。通过指定完成您需要的任务来节省时间,但不要超过这个范围。如果您只想运行单元测试,请选择执行该任务的任务——通常是test。如果要打包应用程序,大多数构建都有一个组装任务。

最后一件事:Gradle的增量构建支持是健壮和可靠的,因此,除非你真的想执行一个清理任务,否则就避免执行清理任务,以保持构建的快速运行。

3.Gradle有几个固定的构建阶段

理解Gradle评估和执行构建脚本分三个阶段是很重要的:

  1. 初始化
    为构建设置环境,并确定哪些项目将参与其中。

  2. 配置
    为构建构建构造并配置任务图,然后根据用户希望运行的任务确定需要运行哪些任务以及以何种顺序运行。

  3. 执行
    运行配置阶段结束时选择的任务。

这些阶段形成了Gradle的构建生命周期。

与Apache Maven术语的比较

Gradle的构建阶段不像Maven的构建阶段。Maven使用它的阶段将构建执行划分为多个阶段。它们扮演着与Gradle任务图相似的角色,尽管没有那么灵活。

Maven构建生命周期的概念与Gradle的生命周期任务大致相似。

设计良好的构建脚本主要由声明性配置组成,而不是命令式逻辑。可以理解的是,在配置阶段对该配置进行评估。即使如此,许多这样的构建也有任务操作——例如通过doLast{}和doFirst{}块——在执行阶段进行评估。这一点很重要,因为在配置阶段评估的代码不会看到在执行阶段发生的更改。

配置阶段的另一个重要方面是,在每次运行构建时都要评估其中涉及的一切。这就是为什么最好的做法是在配置阶段避免昂贵的工作。构建扫描可以帮助您识别这些热点。

4.Gradle可以通过多种方式进行扩展

如果你能只用Gradle附带的构建逻辑来构建你的项目,那就太好了,但这几乎是不可能的。大多数构建都有一些特殊的需求,这意味着您需要添加定制的构建逻辑。

Gradle提供了几种允许你扩展它的机制,例如:

  • 自定义任务类型
    当您希望构建完成一些现有任务无法完成的工作时,您可以简单地编写自己的任务类型。通常最好将自定义任务类型的源文件放在buildSrc目录或打包的插件中。然后你就可以像使用gradle提供的任务类型一样使用自定义任务类型。

  • 自定义任务的行为
    可以通过task . dofirst()和task . dolast()方法附加自定义构建逻辑,在任务之前或之后执行。

  • 项目和任务上的额外属性
    这允许您将自己的属性添加到项目或任务中,然后可以从自己的自定义操作或任何其他构建逻辑中使用这些属性。额外的属性甚至可以应用到你没有明确创建的任务上,比如那些由Gradle的核心插件创建的任务。

  • 自定义约定
    约定是简化构建的强大方法,用户可以更容易地理解和使用它们。这可以在使用标准项目结构和命名约定(如Java构建)的构建中看到。你可以编写自己的插件来提供约定——它们只需要为构建的相关方面配置默认值。

  • 自定义模型
    Gradle允许你在构建中引入新的概念,而不仅仅是任务、文件和依赖配置。您可以在大多数语言插件中看到这一点,它们将源集的概念添加到构建中。对构建过程进行适当的建模可以极大地提高构建的易用性和效率。

5.根据API构建脚本操作

很容易将Gradle的构建脚本视为可执行代码,因为它们就是可执行代码。但这是一个实现细节:设计良好的构建脚本描述构建软件需要哪些步骤,而不是这些步骤应该如何完成工作。这是一项针对自定义任务类型和插件的工作。

有一个常见的误解,认为Gradle的强大和灵活性来自于它的构建脚本是代码这一事实。这与事实相去甚远。底层模型和API提供了这些功能。正如我们在最佳实践中建议的那样,您应该避免在构建脚本中放置太多(如果有的话)命令式逻辑。

然而,将构建脚本视为可执行代码是很有用的:理解构建脚本的语法是如何映射到Gradle的API的。API文档——由Groovy DSL引用和Javadocs组成——列出了方法和属性,并引用了闭包和操作。这些在构建脚本的上下文中意味着什么?请参阅Groovy构建脚本入门,了解这个问题的答案,以便您能够有效地使用API文档。

由于Gradle运行在JVM上,构建脚本也可以使用标准的Java API。Groovy构建脚本还可以使用Groovy api,而Kotlin构建脚本可以使用Kotlin api。