Gradle Incremental Builds: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 8: Line 8:
* [[Gradle_Task#Incremental_Builds|Gradle Tasks]]
* [[Gradle_Task#Incremental_Builds|Gradle Tasks]]


=Overview=
=Incremental Build=
An incremental build is a build that can avoid running tasks whose inputs and outputs did not change, making the execution of such tasks unnecessary. Incremental builds save time, because they avoid doing unnecessary work.


The central element that enables such behavior is the capacity of tasks to analyze their inputs and outputs, detect that nothing changed and decide that they don't need to run.


An even more sophisticated behavior is identifying which of the input elements had changed and only performing the work for those elements. An incremental build is not required to that, it only has to avoid to run tasks unnecessarily. However, Gradle supports the behavior described above with [[Gradle Incremental Builds#Incremental_Task|incremental tasks]].




Line 17: Line 20:




Gradle is designed to allow faster builds by detecting work that does not need to be done, because it was done by a previous build and nothing change since. The central element that enables such behavior is the capacity of tasks to analyze their inputs and outputs, detect that nothing changed and decide that they don't need to run. Such tasks allow [[Gradle Incremental Builds#Incremental_Build|incremental builds]]. An even more sophisticated behavior is identifying which of the input elements had changed and only performing the work for those elements. [[Gradle Incremental Builds#Incremental_Task|Incremental tasks]] do that. Gradle allows caching task output in [[Gradle Build Cache#Overview|build caches]], if the tasks producing those outputs are [[Gradle Build Cache#Cacheable_Task|cacheable tasks]], hence enabling sharing of outputs between builds.  
 
 
 
 
Gradle allows caching task output in [[Gradle Build Cache#Overview|build caches]], if the tasks producing those outputs are [[Gradle Build Cache#Cacheable_Task|cacheable tasks]], hence enabling sharing of outputs between builds.  


{{Internal|Gradle Build Cache#Overview|Builds Cache}}
{{Internal|Gradle Build Cache#Overview|Builds Cache}}

Revision as of 22:56, 18 October 2020

External

Internal

Incremental Build

An incremental build is a build that can avoid running tasks whose inputs and outputs did not change, making the execution of such tasks unnecessary. Incremental builds save time, because they avoid doing unnecessary work.

The central element that enables such behavior is the capacity of tasks to analyze their inputs and outputs, detect that nothing changed and decide that they don't need to run.

An even more sophisticated behavior is identifying which of the input elements had changed and only performing the work for those elements. An incremental build is not required to that, it only has to avoid to run tasks unnecessarily. However, Gradle supports the behavior described above with incremental tasks.






Gradle allows caching task output in build caches, if the tasks producing those outputs are cacheable tasks, hence enabling sharing of outputs between builds. 
Builds Cache



An incremental build is a build that does not execute one or more tasks if it does not need to. Gradle determines whether it needs to execute a task or not by analyzing its inputs and outputs.

Incremental Build

https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks

Task Inputs and Outputs

Gradle determines whether a task is up to date if the task's inputs and outputs have not changed since the last execution, by comparing their values with those preserved in the build cache. Does the build cache need to be enabled for inputs and outputs to be relevant?


If the input and output snapshots are identical to the previous ones, the task is not executed. An input can be a property, a directory or one or more files. An output is a directory or one or more files. Inputs and outputs are fields of the DefaultTask class. Task inputs and outputs are obtained with Task.getInputs() and Task.getOutputs(), which return TaskInputs and TaskOutputs instances, respectively.

Task inputs and outputs are evaluated during the configuration phase to wire up the task dependencies. That is why they need to be defined in a configuration block. To avoid unexpected behavior, make sure that the value you assign to inputs and outputs is accessible at configuration time. If you need to implement programmatic output evaluation, the method upToDateWhen(Closure) on TaskOutputs comes in handy. In contrast to regular inputs/outputs evaluation, this method is evaluated at execution time. If the closure returns true, the task is considered up to date.

Debug a Java compilation task to see how input/output works.

Annotations

@Input

https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/Input.html

⚠️ Note that in Java, the annotation must be attached to the getter method. Annotations on setters or just the field in Java are ignored.

@OutputFile

https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/OutputFile.html

Up-to-date Check

UP-TO-DATE

Incremental Task

Incremental Task

Build Cache

Build Cache