Gradle Release Notes

Version 4.5

The Gradle team is pleased to announce Gradle 4.5.

First and foremost, this release of Gradle features improvements to the build cache:

In addition to cacheability improvements for native development, incremental compilation for C/C++ does finer-grained analysis of dependencies between source files and header files, which will result in fewer files compiled and a higher cache hit-rate. Read details about C and C++ compilation improvements here.

Now on to performance improvements everyone can enjoy: less memory consumption and faster up-to-date behavior. Gradle 4.5 features much more memory-efficient incremental compilation. Combined with less file canonicalization, faster task selection, and faster variant-aware dependency resolution, this results in up to 30% faster up-to-date checking. The improvement will be especially pronounced for projects with a large number of constants, as is typical in Android projects. For example, here are 2 snapshots comparing cross-build caches.

The 1st one from Gradle 4.4 using 440MB:

Gradle 4.4 heap dump

This 2nd snapshot from Gradle 4.5 using 280MB:

Gradle 4.5 heap dump

Next up, you can finally sign artifacts using gnupg-agent. Special thanks to Christoph Böhme for contributing this highly-anticipated feature.

Documentation has been upgraded in this release, with use-case oriented examples for several highly trafficked pages, improved navigation, and a more pleasant experience in many ways. Read details about the improvements, or just start with the new docs home page.

Individual deprecation warnings are no longer displayed in console output by default, as many users often cannot take action on deprecation warnings from third party plugins. You can now control the verbosity of logging deprecation warnings.

Last but not least, 2 Kotlin DSL updates:

We hope you will build happiness with Gradle 4.5, and we look forward to your feedback via Twitter or on GitHub.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

C/C++ compilation improvements

Build Cache Support

We introduced experimental C/C++ caching support in Gradle 4.3, but this feature was hidden behind an additional flag until we had fixed some underlying correctness issues.

In this release, we have fixed some underlying issues with calculating the correct build cache key for C++ compilation and have removed the special flag. If you enable the build cache, Gradle will try to reuse task outputs from C/C++ compile tasks when all inputs (compiler flags, source, dependencies) are identical, which can greatly reduce build times.

Please note that there are some caveats when using the build cache. In particular for C++, object files that contain absolute paths (e.g., object files with debug information) are reusable and cacheable, but may cause problems when debugging.

Incremental Compilation

Gradle's incremental C/C++ compilation works by analysing and understanding the dependencies between source files and the header files that they include. Gradle can use this information to compile only those source files that are affected by a change in a header file. In some cases, Gradle could not analyze all of these dependencies and would assume all source files depend on all header files. Changes to any header file would require recompiling all source files, regardless of whether the compiler output would change or not. This also affected how well the Gradle build cache could be used to skip compilation.

In this release, Gradle's incremental C/C++ compilation is now able to understand most dependencies between source files and header files. This means incremental compilation will occur more often and builds are more likely to see cache hits.

ANTLR task is now cacheable by default

When generating grammar sources with ANTLR, now the task's outputs are stored and retrieved from the build cache.

Documentation enhancements

This release of Gradle adds more examples and use-case oriented documentation. In particular, notable improvements have been made to documentation for the command-line interface, configuring the build environment, dependency management, and Gradle wrapper.

In addition, major improvements were made to discoverability of content through improved navigation in the user manual and DSL reference. docs.gradle.org now loads faster (especially in Asia), is more mobile-friendly, and gives you a much better sense of where you are.

docs star ratings and edit widget

Your feedback will be very helpful for continued improvement, which you can provide through new "star ratings" and "edit this page" functionality on each user manual page, in addition to GitHub issues.

Signing artifacts with gpg-agent

You can now sign generated artifacts via GnuPG's agent. Example usage:

signing {
    useGpgCmd()
    sign configurations.archives
}

Please see signing plugin documentation for more details.

Reduced deprecation logging in console

In this release, deprecation warnings are no longer displayed in the console output by default. Instead, all deprecation warnings in the build will be collected and a summary will be rendered at the end of the build.

You can run the build with the command line option --warning-mode=all or the property org.gradle.warning.mode=all to have all warnings displayed as earlier version of Gradle. You can use the command line option --warning-mode=none or the Gradle property org.gradle.warning.mode=none to suppress all warnings, including the one displayed at the end of the build.

Learn more about customizing logging warnings in the command-line interface documentation.

Init task can now generate Kotlin DSL build scripts

It is now possible to generate new Gradle builds using the Kotlin DSL with the help of the init task and its new --dsl option:

gradle init --dsl kotlin

The new option defaults to groovy and is supported by all build setup types except migration from Maven builds.

See the user guide section on the init plugin for more information.

New plugin APIs

Provider API - SetProperty

A convenience for dealing with sets has been added to the Provider API.

Use of runtime types when declaring @Nested task inputs

When analyzing @Nested task properties for declared input and output sub-properties, Gradle used to only observe the declared type of the property. This meant ignoring any sub-properties declared by a runtime sub-type.

Since Gradle 4.5, Gradle uses the type of the actual value instead, and hence can discover all sub-properties declared this way.

Rich Java compiler arguments

When you have to expose a file location to your annotation processor, it is essential for Gradle to learn about this additional input (or output). Without tracking the location and contents of the given file (or directory), features like incremental build and task output caching cannot function correctly. Before Gradle 4.5, you had to let Gradle know about such inputs or outputs manually by calling compileJava.inputs.file(...) or similar.

Gradle 4.5 introduces a better way to handle this situation by modeling the annotation processor as a CompilerArgumentProvider. This approach allows the declaration of complex inputs and outputs, just like how you would declare @InputFile and @OutputDirectory properties on the task type.

For example, to declare annotation processor arguments, it is now be possible to do the following:

class MyAnnotationProcessor implements CompilerArgumentProvider {
        @InputFile
        @PathSensitivite(NONE)
        File inputFile

        @OutputFile
        File outputFile

        MyAnnotationProcessor(File inputFile, File outputFile) {
            this.inputFile = inputFile
            this.outputFile = outputFile
        }

        @Override
        List<String> asArguments() {
            [
                "-AinputFile=${inputFile.absolutePath}",
                "-AoutputFile=${outputFile.absolutePath}"
            ]
        }
    }

    compileJava.options.compilerArgumentProviders << new MyAnnotationProcessor(inputFile, outputFile)

This models an annotation processor which requires an input file and generates an output file.

The approach is not limited to annotation processors, but can be used to declare any kind of command-line argument to the compiler. The only thing you need to do is to add your custom CompilerArgumentsProvider to CompileJava.options.compilerArgumentProviders.

@Nested on iterables

When applying the @Nested to an iterable property, each element is now treated as a separate nested input. CompileJava.options.compilerArgumentProviders shows this new behavior:

@Nested
@Incubating
public List<CompilerArgumentProvider> getCompilerArgumentProviders() {
    return compilerArgumentProviders;
}

Default CodeNarc has been upgraded to 1.0

Now CodeNarc's default version has been upgraded to 1.0, enjoy!

Configure executable directory in distributions

Previously, executables in distributions would be placed in bin directory and couldn't be configured. Now you can configure this directory with executableDir property.

See application plugin for more details.

Arbitrary task property names

When registering task properties via the runtime API, property names are not required to be Java identifiers anymore, and can be any non-empty string.

Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to backwards compatibility. See the User guide section on the “Feature Lifecycle” for more information.

The following are the features that have been promoted in this Gradle release.

Fixed issues

Deprecations

Features that have become superseded or irrelevant due to the natural evolution of Gradle become deprecated, and scheduled to be removed in the next major Gradle version (Gradle 5.0). See the User guide section on the “Feature Lifecycle” for more information.

The following are the newly deprecated items in this Gradle release. If you have concerns about a deprecation, please raise it via the Gradle Forums.

Deprecation of no-search-upward command line options

The command line options for searching in parent directories for a settings.gradle file (-u/--no-search-upward) has been deprecated and will be removed in Gradle 5.0. A Gradle project should always define a settings.gradle file to avoid the performance overhead of walking parent directories.

Potential breaking changes

Build Cache

HTTP build cache does not follow redirects

When connecting to an HTTP build cache backend via HttpBuildCache, Gradle does not follow redirects any more, and treats them as errors instead. Getting a redirect from the build cache backend is mostly a configuration error (e.g. using an http url instead of https), and has negative effects on performance.

Build cache configuration of included builds no longer respected

In earlier versions of Gradle, each included build within a composite used its own build cache configuration. Now, included builds inherit the configuration from the root build. Included builds may still define build cache configuration in their settings.gradle file, it is just no longer used.

This change will not cause build breakage and does not require any change in build logic to adapt to.

Included builds of composite build now share build cache configuration

Previously, each build within a composite build used its own build cache configuration. Now, included builds, and their buildSrc builds, automatically inherit the build cache configuration of the root build. This makes managing build cache configuration for composite builds simpler and effectively allows better build cache utilization.

Included builds may still define build cache configuration in their settings.gradle file, it is just no longer respected.

The buildSrc build of the root project continues to use its own build cache configuration, due to technical constraints. However, the buildSrc build of any included build will inherit the build cache configuration from the root build. For more on configuring the build cache for the root buildSrc build, please see the documentation for using the build cache.

Incubating Depend task removed

The Depend task has been removed without a replacement. Its capability has been merged into the respective native compilation tasks.

Gradle no longer tracks the canonical path of input file tree roots

Gradle was inconsistently handling symlinks when snapshotting inputs. For the root of a file tree it would take the canonical path into account. For individual files and contents of trees, it would only consider the normalized path instead. Gradle will now always use the normalized path. This means that a task will not rerun if a directory is replaced with a symlink to the exact same contents. If you have a use case that requires reacting to the canonical path of inputs, please open an issue and we'll consider an opt-in API that will canonicalize all inputs, not just tree roots.

Project.file() no longer normalizes case

The Project.file() and related methods used to normalize the case on case-insensitive file systems. This means that the method would check whether any parts of the hierarchy of a given file already existed in a different case and would adjust the given file accordingly. This lead to lots of IO during configuration time without a strong benefit.

The Project.file() method will now ignore case and only normalize redundant segments like /../. It will not touch the file system.

ListProperty no longer extends Property

ListProperty now extends HasMultipleValues and Provider instead of Property. The Property interface represents a property whose incoming and outgoing types are the same. A List can be assembled from any Iterable rather than just any List, so the new arrangement reflects this to allow a ListProperty<T> to be set using any Iterable<T>.

This also applies to the DSL. The Groovy DSL will allow any Iterable to be used to set the value of a ListProperty.

The new SetProperty type follows this same pattern.

External contributions

We would like to thank the following community members for making contributions to this release of Gradle.

We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.

Known issues

Known issues are problems that were discovered post release that are directly related to changes made in this release.