介绍持续构建执行
优化构建-编辑-构建循环 #
过去,我们建议您启用 Gradle 守护进程(以及并行执行,但有一些注意事项)以获得 Gradle 的最佳性能。我们还讨论过使用 增量构建 来加速您的构建-编辑-构建反馈循环,方法是跳过不必要的工作。现在还有另一种优化方法可用——这种方法可以让您摆脱困境,让 Gradle 为您启动构建。
从 2.5 版本开始,Gradle 支持持续构建执行,当检测到其输入发生更改时,它将自动重新执行构建。已经有一些社区插件添加了对 Gradle “watch”模式 的支持,这些插件的功能类似。
对于 Maven,相同的 watch 功能需要为每个插件实现,或者您必须使用具有预定义目标集的插件。我们想做得更好。我们希望任何插件都能够利用持续构建的强大功能,而无需提供额外的信息。我们还希望要执行的任务集是完全临时的。由于 Gradle 需要知道任务的输入和输出才能进行增量构建,因此我们拥有开始监视更改所需的所有信息。
使用持续构建 #
持续构建 可以与任何具有已定义输入和输出的任务或任务集一起使用。如果您使用行为良好的任务,这对大多数构建来说应该不是问题。如果您发现您的构建没有像您认为的那样使用持续构建进行重建,则可能表明您的构建脚本中存在问题。
命令行选项 #
您可以使用 -t
或 --continuous
命令行选项以及您想要运行的任何任务(我们称之为任务选择器)来启用持续构建。至少需要有一个运行的任务定义输入才能进入持续构建模式。
例如,在一个典型的 Java 项目中,
$ gradle -t test
将启用持续构建,并在主源代码或测试源代码发生更改时重新运行测试。
我们不限于单个任务,因此我们也可以使用以下命令在主源代码上重新运行测试和 FindBugs:
$ gradle -t test findBugsMain.
确定何时运行另一次构建 #
当您使用持续构建选项运行 Gradle 时,Gradle 会像往常一样执行构建,除了 Gradle 还会将所有任务的输入注册到文件监视服务。即使是 UP-TO-DATE
的任务也会记录其输入,因此在触发新构建时可以考虑所有输入。这意味着您不必从干净的构建开始,Gradle 也能知道哪些输入可能会在持续构建模式下发生更改。
在构建结束后,Gradle 将开始根据收集的输入监视文件系统更改。Gradle 命令行界面将在控制台上显示消息 Waiting for changes to input files of tasks
,并等待输入的更改。如果任何输入文件被更改或删除,Gradle 将使用相同的任务选择器集执行另一次构建。Gradle 可以检测对简单文件(已删除、已修改)和目录(已删除或新文件)的更改。
观看此功能的演示
退出持续构建 #
一旦 Gradle 在持续构建中运行,它就不会退出,即使构建不成功也是如此。要退出持续构建,您应该使用 Ctrl-D
来取消构建。在 Microsoft Windows 上,您还必须在 Ctrl-D
之后按 ENTER
或 RETURN
。
如果您使用 Ctrl-C
,Gradle 将突然退出,并同时杀死 Gradle 守护进程。
更新:从 Gradle 3.1 开始,Ctrl-C
不再杀死 Gradle 守护进程。
局限性 #
用户指南章节 描述了持续构建的所有局限性和怪癖。
需要 Java 7 或更高版本 #
Gradle 使用 Java 7 的 WatchService 来监视输入的更改。此功能仅在 JDK 7 或更高版本上可用。
Mac OS X 性能 #
对于 GNU/Linux 和 Microsoft Windows,文件系统更改事件是通过内核服务提供的。对于 Mac OS X,Java 退回到基于轮询的系统。这意味着仅在 Mac OS X 上,对大量输入文件的更改检测可能会延迟,并且在某些情况下,可能会导致死锁。这两个问题都在 JDK 错误中跟踪:JDK-7133447 和 JDK-8079620。
构建脚本的更改 #
在持续构建模式下,Gradle 不考虑对您的构建逻辑的更改。构建逻辑是从 build.gradle
、settings.gradle
、gradle.properties
和其他来源创建的。如果您对构建脚本进行更改,您必须退出持续构建并重新启动 Gradle。未来版本的 Gradle 将使其更容易描述构建逻辑的输入,以便持续构建也可以使用它。
未来的改进 #
除了减轻当前实现的一些局限性之外,我们还可以使用持续构建来完成其他有趣的事情。
目前,没有任何受支持的公共方法来管理由 Gradle 启动的需要在构建之间存在的进程。Gradle 期望启动的进程(例如,通过 Exec
启动)将作为构建的一部分退出。
在下一个版本 (2.6) 中,Play 支持将添加到 Gradle 中,这样您就可以在单独的 JVM 中启动 Play 应用程序以进行本地开发。启用持续构建后,每当类或资产发生更改时,Gradle 将热重载 Play 应用程序。Play 插件通过以在构建之间生存的方式向 Gradle 注册 Play JVM 来实现此目的。
我们希望最终将这种特定于 Play 的重新加载功能发展为通用功能,以便插件可以拥有自己的“热重载”类行为。
另一个改进机会是最新检查。对于非常大的项目,最新检查对于无操作情况可能非常耗时。在查找过时文件时,Gradle 必须扫描整个目录或重新计算文件校验和。当使用持续构建时,Gradle 必须已经跟踪文件和目录更改,因此在某些情况下,Gradle 可能能够跳过对已知未更改文件的检查。
反馈 #
如果您在使用此新功能时遇到任何意外情况,请在论坛上告知我们。