On 02/11/2010, at 1:33 AM, Ross Sargant wrote:

> OK. I was able to get this to work for my current needs by doing this (I 
> actually have a few libraries to deal with beside the flash one)
> 
> task('image',type:TiniConvert,dependsOn:[compileJava,flashLibrary,psDriver,mpiDriver,pdiDriver]){
>     
>  
> nativeLibs=files([tasks['flashLibrary'].outputFile,tasks['psDriver'].outputFile,tasks['mpiDriver'].outputFile,tasks['pdiDriver'].outputFile])
>      
> }
> 
> And declaring both the native libraries and class files as @InputFiles on the 
> conversion task. This seems to be giving me a fully functional incremental 
> build. The only issue is the small "duplication" smell between dependsOn and 
> nativeLibs but it sounds like that would be remedied by your idea.
> 
> Just a suggestion but it would be helpful to document how the file change 
> detection works somewhere. I spent quite a bit of time struggling to 
> understand why my assembly code change wasn't kicking off an image task after 
> the above mods but it was because the change I was making to the source file 
> was adding blank lines which the external assembler stripped back out :).
> 
>  I had assumed the change detection worked off last modified time of the file 
> which was changing when I did the above so I couldn't figure out why the 
> library was always considered up to to date.  Once I figured out this was the 
> problem, it worked perfectly when I made a change to the source that changed 
> the final binary output file :) This is a great behavior (more optimal change 
> detection) but it would be nice to have it documented somewhere if not 
> already.

There's a little bit about it in the user guide already: 
http://www.gradle.org/0.9-rc-2/docs/userguide/more_about_tasks.html#N10E10

The docs still need more work, but should give the basic idea of how it works.

> 
> 
> On Mon, Nov 1, 2010 at 4:32 AM, Adam Murdoch <[email protected]> wrote:
> 
> On 30/10/2010, at 2:25 AM, Ross Sargant wrote:
> 
>> Adam,
>>   Thanks very much for the advice. I assume in your suggested approach that
>>  
>> "destFile" would be marked as @OutputFile in CompileNative and
>> 
>> "srcFile" would be marked as @InputFile in TiniConvert?
> 
> Yes
> 
>> 
>> I'm curious how gradle determines it has to run the "flashLibrary" task when 
>> I run the "image" task without using "dependsOn" ?
> 
> It doesn't yet. I'd like to add that.
> 
> 
>> What actually makes that work? The fact that @InputFile and @OutputFile 
>> point to the same file object? 
> 
> That they point to the same file.
> 
>> 
>> 
>> 
>> On Thu, Oct 28, 2010 at 8:22 PM, Adam Murdoch <[email protected]> wrote:
>> 
>> On 29/10/2010, at 5:25 AM, Ross Sargant wrote:
>> 
>>> Hi!
>>>   
>>> To learn some of the "ins & outs" of Gradle, I'm attempting to changeover 
>>> and existing ant build process to a native gradle one.  The build process 
>>> is generating a binary image file which gets loaded on to a flash memory 
>>> part. Its not a particularly complex build but it does call out to several 
>>> external tools. In a nutshell the process is
>>> 
>>> 1) Compile high level java code
>>> 
>>> 2) Compile several different sets of assembly code into native libraries (1 
>>> output file per library)
>>> 
>>> 3) Run a conversion program which glues the output of #1 and #2 together to 
>>> produce the final loadable image file.
>>> 
>>> I'm trying to make full use of the incremental build capabilities but I 
>>> think I'm missing something in the "theory of operation".  I defined a 
>>> "CompileNative'  task type using @InputFile and @OutputFile which handles 
>>> calling the necessary tools. I then defined a task for each library I need 
>>> to build.
>>> 
>>> task('flashLibrary',type:CompileNative){
>>>     sourceFile=new File("${project.nativeSrc}/flash/FlashIOP.a51")
>>> }
>>> 
>>> The incremental support is working great w.r.t to this task alone. If I 
>>> change the source file, delete the output file..etc it rebuilds the 
>>> library. Perfect.
>>> 
>>> The final task which handles step #3 looks like this:
>>> 
>>> task('image',type:TiniConvert,dependsOn [compileJava,flashLibrary]){
>>>        
>>> }
>>> 
>>> My issue is that when I do a "gradle image" AND the flashLibrary is 
>>> determined to be out of date and re-executed, the 'image' task does not 
>>> execute (considered up to date) although it needs to execute again to 
>>> incorporate the modified library.
>>> 
>>> Now, I kind of understand this because my "TiniConvert' task does not 
>>> formally mark the binary library files as Inputs. However, it seems better 
>>> to me if the gradle task dependency engine could somehow handle that for 
>>> me. Since 'image' is a dependent of 'flashLibrary' and flashLibrary was 
>>> re-executed shouldn't that mean 'image' will re-execute as well or is that 
>>> only true if I formally configure 'TiniConvert' with the output of the 
>>> dependent tasks marked as @Input?
>> 
>> You need to mark it as an @Input (or @InputFile, more likely?).
>> 
>> Gradle could certainly infer that the flashLibrary is an input of the image 
>> task. Or more generally, that a file produced by a dependency of a task is 
>> an input for the task. But that's not necessarily true. It's very likely, 
>> but not necessarily so.
>> 
>> Instead, I would rather that we flipped things around, so that when you say 
>> that the flashLibrary is an input of the image task, then Gradle can infer 
>> that the flashLibrary task is a dependency of the image task. That is, you'd 
>> do something like:
>> 
>> task('flashLibrary', type: NativeCompile) {
>>     destFile = flashLibOutputFile
>> }
>> 
>> task('image', type: TiniConvert) {
>>    srcFile = flashLibOutputFile // or srcFile = flashLibrary.destFile
>> }
>> 
>> Using artifact dependencies such as this, rather than task dependencies, 
>> have some advantages. They more accurately model the world: the 'image' task 
>> needs a flash library as input, but it doesn't really care how that library 
>> is produced. This gives Gradle some flexibility about how it builds the 
>> flash library. It might build it on another machine. It might substitute in 
>> a pre-built one it downloads from a repository, or another developer 
>> machine. Or Gradle might give you a way to implement rules like: when I'm 
>> doing a release, the flash library must be tested before it can be used as 
>> an input to another task.
>> 
>> 
>> --
>> Adam Murdoch
>> Gradle Developer
>> http://www.gradle.org
>> CTO, Gradle Inc. - Gradle Training, Support, Consulting
>> http://www.gradle.biz
>> 
>> 
>> 
>> 
>> -- 
>> Ross Sargant
>> Software Engineer
>> p: 954-623-6015 x2108
>> email: [email protected]
>> 
>> TVR Communications LLC
>> 541 S. State Road 7,Suite 5,Margate, Florida,33068
>> 
>> http://www.tvrc.com
>> 
> 
> 
> 
> --
> Adam Murdoch
> Gradle Developer
> http://www.gradle.org
> CTO, Gradle Inc. - Gradle Training, Support, Consulting
> http://www.gradle.biz
> 
> 
> 
> 
> -- 
> Ross Sargant
> Software Engineer
> p: 954-623-6015 x2108
> email: [email protected]
> 
> TVR Communications LLC
> 541 S. State Road 7,Suite 5,Margate, Florida,33068
> 
> http://www.tvrc.com
> 


--
Adam Murdoch
Gradle Developer
http://www.gradle.org
CTO, Gradle Inc. - Gradle Training, Support, Consulting
http://www.gradle.biz

Reply via email to