Gradle Release Notes

Version 1.11

Gradle 1.11 primarily features improvements to the rapidly evolving native support. The new Visual Studio integration means that it is now possible to easily generate Visual Studio configuration files that allow you to develop your Gradle based native project. The support for pre-built native dependencies is also a strong step forward and makes Gradle a compelling build tool choice for a new class of native code projects.

As always there are bug fixes and internal performance and stability improvements, along with a mix of other new and improved features. Thanks to all who submitted contributions, bug reports and ideas for the release.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

Choose applicable platforms, build types and flavors for a native component incubating feature

It is now possible to specify a global set of build types, platforms and flavors and then specifically choose which of these should apply for a particular component. This makes it easier to have a single plugin that adds support for a bunch of platforms, build types, and/or flavors, and have the build script choose which of these are appropriate.

model {
    platforms {
        x86 {
            ... config
        }
    }
    buildTypes {
        debug
    }
    flavors {
        custom
    }
    ... Many others, perhaps added by capability plugins
}

executables {
    main {
        targetPlatforms "x86" // Only build for this platform
        targetFlavors "foo", "bar" // Build these 2 flavors
        // targetBuildTypes - without this, all build types are targeted.
    }
}

Current Limitations

  • The component.target* methods match on element name. It is not possible to supply an element instance at this time.

Improved notation for declaring library dependencies when building native binaries incubating feature

When building native binaries, it is now possible to declare a dependency on a library using a dependency notation.

libraries {
    hello
}

executables {
    main
}
sources {
    main {
        cpp {
            lib library: 'hello', linkage: 'static'
        }
        c {
            lib project: ':another', library: 'hi'
        }
    }
}

The project, library and linkage attributes can be specified. Only library is required and must be the name of a library in the specified project, or in the current project if the project attribute is omitted.

This notation based syntax provides a number of benefits over directly accessing the library when declaring the dependency requirement:

Declare header-only library dependencies in native binary projects incubating feature

There are times when your source may require the headers of a library at compile time, but not require the library binary when linking. To support this use case, it is now possible to add a dependency on the 'api' linkage of a library. In this case, the headers of the library will be available when compiling, but no binary will be provided when linking.

A dependency on the 'api' linkage can be specified by both the direct and the map-based syntax.

sources {
    main {
        cpp {
            lib project: ':A', library: 'my-lib', linkage: 'api'
            lib libraries.hello.api
        }
    }
}

Include pre-built libraries in native binary projects incubating feature

It would be very unusual for a sophisticated software project not to make some use of 3rd party system libraries. In some cases these libraries are already available locally. This version of Gradle makes it possible to reference these 'pre-built' libraries such that they can be referenced as a dependency in the same way as libraries built by Gradle.

In order to reference pre-built libraries, they must be added to a local repository of type PrebuiltLibraries. For each library, the header directories to include can be defined, as well as the actual binary files for static and shared library linkages.

model {
    repositories {
        libs(PrebuiltLibraries) {
            boost {
                headers.srcDir "libs/boost_1_55_0/boost"
            }
            util {
                headers.srcDir "libs/util/src/include"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("libs/util/bin/libutil.a")
                }
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("libs/util/bin/libutil.so")
                }
            }
        }
    }
}

Future releases of Gradle will provide full-featured dependency resolution for third-party libraries, as well as providing more sophisticated support for system libraries (such as the Windows SDK). PrebuiltLibraries takes a step in that direction, and provides a tool that can be used for many use cases.

Support for generated sources in native binary projects incubating feature

Any LanguageSourceSet (e.g. CSourceSet, CppSourceSet) is now a BuildableModelElement, which means that a task can be supplied which will be executed before the sources are used. This makes it easy to include generated sources in your native binary project.

A 'builder' task for a source set can be added using the builtBy method. All such tasks will be executed before the source set is used. The source set files and headers will still need to be explicitly configured, either as directory paths or by connecting task outputs.

sources {
    main {
        c {
            builtBy tasks.generateCSources
            source {
                srcDirs tasks.generateCSources.sourceDir
            }
            exportedHeaders {
                srcDirs tasks.generateCSources.headerDir
            }
        }
    }
}

As an added convenience, it is possible to specify that a source set is generatedBy a particular task. As well as linking the task as a 'builder' for the source set, Gradle will also inspect the generator task for sourceDir and headerDir output properties, which will then be automatically configured as source set inputs.

Using this mechanism, the above example can be simplified to:

source {
    main {
        c {
            generatedBy tasks.generateCSources
        }
    }
}

See the idl sample in your Gradle distribution for a working example of generated sources for a native binary.

Objective-C and Objective-C++ Support incubating feature

With Gradle 1.11, it is now possible to include 'Objective-C' and 'Objective-C++' source files to create a native library or executable. Including Objective-C and Objective-C++ sources in your project is straightforward. Whereas C++ sources are contained in a 'cpp' source directory, Objective-C source files should be located in a 'objectiveC' directory and Objective-C++ source files in a 'objectiveCpp' directory. These directory locations are by convention, and can be updated in your build script.

Here's an example of how you can customize which source files and directories to include:

sources {
    main {
        // Configure an existing ObjectiveCSourceSet
        objectiveC {
            source {
                srcDirs "objectiveCFiles"
                include "**{@literal /}*.m"
            }
            exportedHeaders {
                srcDirs "includes"
            }
        }

        objectiveCpp {
            source {
                srcDirs "src/shared/objectiveCpp"
                include "**{@literal /}*.mm"
            }
            exportedHeaders {
                srcDirs "src/main/include"
            }
        }
    }
}

Generate Visual Studio configuration for a native binary project incubating feature

One of the great things about using Gradle for building Java projects is the ability to generate IDE configuration files: this release of Gradle brings a similar feature when you use Microsoft Visual Studio as your IDE. With this integration, you can use the best tool for the job: Gradle to build your binaries and Visual Studio to edit your code.

Visual Studio integration is supplied by the visual-studio plugin. When this plugin is applied, for each component Gradle will create a task to produce a Visual Studio solution for a selected binary variant of that component. The generated solution will include a project file for the selected binary, as well as project files for each depended-on library.

Similar to the Java IDE plugins, you can customize the generated Visual Studio configuration files with programmatic hooks. These hooks are applied to the visualStudio element in the model registry. For example, you can change the default locations of the generated files:

model {
    visualStudio {
        solutions.all { VisualStudioSolution solution ->
            solutionFile.location = "vs/${solution.name}.sln"
        }
        projects.all { VisualStudioProject project ->
            projectFile.location = "vs/${project.name}.vcxproj"
            filtersFile.location = "vs/${project.name}.vcxproj.filters"
        }
    }
}

Additionally, you can change the content of the generated files:

model {
    visualStudio {
        solutions.all { VisualStudioSolution solution ->
            solutionFile.withText { StringBuilder text ->
                ... customise the solution content
            }
        }
        projects.all { VisualStudioProject project ->
            projectFile.withXml { XmlProvider xml ->
                xml.asNode()...
            }
        }
    }
}

While Visual Studio support is functional, there remain some limitations:

Please try it out an let us know how it works for you.

Improved detection of Visual studio and Windows SDK installations

Independent control of TestNG output directory

It is now possible to specify the location that TestNG should write its output files to. In previous versions of Gradle, this location was inseparable from the location that Gradle writes its output files to.

It can be set via the TestNGOptions.outputDirectory property, which can be set during the useTestNG() configuration closure…

test {
  useTestNG {
    outputDirectory = file("$buildDir/testngoutput")
    useDefaultListeners()
  }
}

By default, the value for this new property will be the same as the value for the destination property of the test task's HTML report.

If you are using the file outputs from TestNG listeners (i.e. you are calling useDefaultListeners() or registering a custom listener), it is recommended that you explicitly set this new property to a value other than the default. The default value for this property will change in Gradle 2.0.

Fixed issues

Potential breaking changes

Change to '?' wildcard in file patterns

Previously, the '?' character would match zero or more characters. To better match the Ant behaviour, the '?' character now matches exactly one character.

Changed DSL and model for native binary components

Much of the model and DSL for defining native binary components has been changed. Most build scripts leveraging this functionality will need to be updated.

Changes to native binary support

Removal of incubating 'cpp-exe' and 'cpp-lib' plugins

These incubating plugins have been removed in Gradle 1.11. Both plugins were very light additions to the cpp plugin which remains.

If you are using the cpp-exe or cpp-lib, you will need to now explicitly create your main executable or library respectively.

A requested dependency returns different types of selectors

The method DependencyResult.getRequested() method was changed to return an implementation of type ComponentSelector. This change to the API has to be taken into account when writing a Spec for the DependencyInsightReportTask. Here's an example for such a use case:

task insight(type: DependencyInsightReportTask) {
    setDependencySpec { it.requested instanceof ModuleComponentSelector && it.requested.module == 'leaf2' }
}

Changes to resolution result root identifier

The root node identifier for a resolved project configuration was changed to return a ProjectComponentIdentifier. Before the change the method ResolutionResult.getRoot().getId() exclusively returned a ModuleComponentIdentifier.

Changes to container configuration DSL

In previous versions of Gradle, accessing a property on the configuration container would create a new configuration on demand if a configuration with the name of the property did not exist. In Gradle 1.11, this behavior only now occurs when inside the configurations script block…

configurations.xyz // will not create configuration 'xyz'

configurations {
  xyz // will create configuration 'xyz'
}

The previous behavior was surprising in certain circumstances and has been removed.

Changes to incubating test filtering

JUnit tests that JUnit API internally represents by 'null' test methods are filtered only by class name. This is a very internal change and should not affect users. It is mentioned for completeness.

Changes to HTML test reports

Ignored tests are no longer considered in the calculation of the reported percentage success rate. A test run with 1 failed test, 1 successful test and 8 ignored tests will now report a success rate of 50% (previously it would have been 90%)

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.