How do I augment a legacy ant task with inputs and outputs in order to leverage the incremental build feature in gradle?

I have a legacy ant build and am trying to slowly migrate to gradle. I created a trivial build.gradle file that simply imports the legacy build.xml file. This allows me to call 'gradle ’ just fine. But now I want to add inputs and outputs to targets in order to take advantage of the incremental build feature in gradle.

Let’s say I a simple ant target that just copies files from one location to another. Let’s call it the copyStuff target. I can then augment this ant target in my new gradle build like this:

copyStuff {
      outputs.files "/new/location/",

Running “gradle copyStuff” works as expected. The first time it runs the ant target, and the second time it says UP-TO-DATE.

This does NOT work though if the legacy target copyStuff is wrapped inside another ant target. Let’s say my legacy ant build has 10 steps, of which copyStuff is just one step. My legacy ant build has a “build” target which includes calls to 10 other ant targets. If I run “gradle build”, it proceeds to call the ant build target and subsequently all 10 other targets. And it ALWAYS calls those 10, despite the fact that copyStuff now has declared inputs and outputs.

So in summary, “gradle copyStuff” works as expected. But “gradle build” does not.

Any ideas on how to get around this problem because I’d love to start the slow migration from ant to gradle without having to muck around with the old ant build.


Do you mean “depends on 10 other Ant targets”?

No. The main build target has ten antcalls.

I don’t think this will work without modifying your Ant build to some extant. My understanding is that once Gradle calls into an Ant target, all of the dependent targets are going to be run. The only way to override this is to manually disable a specific target.

If you have a build with multiple ant projects then Gradle can be leveraged to link them together with incremental build support. If you need to go down to a sub-project level it might not be worth the effort/risk to get each target running incrementally.

I’m afraid there is no way to make up-to-date checks work for targets invoked using antcall. There is no equivalent concept in Gradle, and the import treats targets as a black box.

Moving the target from an ‘antcall’ to a ‘depends’ made things work again. So now I need to think about the best way to solve this overall. Thanks guys!