Configuring the inputs for a task that are created in execution phase

We have a task that creates files that are the inputs for another task. Unfortunately, the configuration phase doesn’t see these files and mistakenly considers the other task up to date. How can I get the task that is dependent on these dynamically created files to build the first time?

A couple of other questions related to the C plugin are:

Is this the best way to make your build dependent on the cspiceStaticLibrary task?

How do you make the cpiceStaticLibrary task (which was dynamically created) dependent on other tasks?

Here’s a small example that doesn’t compile the C code the first time through:

// Create a file mice/src/cspice/foo.c with the content
//
 #include <stdio.h>
//
 foo() {printf("Hello, world!");}
// and then call "tar -czf mice.tar.gz mice"
  apply plugin: 'c'
  defaultTasks 'assemble'
  sources {
    cspice {
        c {
            source {
                srcDir "$buildDir/mice/src/cspice"
                include "**/*.c"
            }
        }
    }
}
  libraries {
    cspice {
        binaries.all {}
    }
}
  task extractTar(type: Exec) {
    mkdir buildDir
      inputs.file "mice.tar.Z"
    outputs.dir "$buildDir/mice"
      commandLine "tar", "-xf", "mice.tar.gz", "-C", buildDir
}
  assemble.dependsOn extractTar
assemble.dependsOn "cspiceStaticLibrary"
------------------------------------------------------------
Gradle 1.11
------------------------------------------------------------
  Build time:
 2014-02-11 11:34:39 UTC
Build number: none
Revision:
   a831fa866d46cbee94e61a09af15f9dd95987421
  Groovy:
     1.8.6
Ant:
        Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:
        2.2.0
JVM:
        1.7.0_51 (Oracle Corporation 24.51-b03)
OS:
         Linux 2.6.32-431.11.2.el6.x86_64 amd64

Unfortunately, the configuration phase doesn’t see these files and mistakenly considers the other task up to date.

It doesn’t have to. The up-to-date check happens in the execution phase, immediately before the task gets executed. If this is about the ‘extractTar’ task, the inputs don’t seem to match the command line (‘mice.tar.Z’ vs. ‘mice.tar.gz’).

Sorry about the typo. Both should be the same. Even with the typo fixed in my example, I still get the following:

$ gradle assemble
:createCspiceStaticLibrary UP-TO-DATE
:cspiceStaticLibrary UP-TO-DATE
:extractTar
:assemble

The question may also be, how get I get the cspiceStaticLibrary task to depend on extractTar?

If I add ‘cspiceStaticLibrary.dependsOn extractTar’, I get the error:

Could not find property 'cspiceStaticLibrary' on root project 'tmp'.

If I add ‘“cspiceStaticLibrary”.dependsOn extractTar’, I get the error:

No signature of method: java.lang.String.dependsOn() is applicable for argument types: (org.gradle.api.tasks.Exec_Decorated) values: [task ':extractTar']

If I understand correctly, the sources for the ‘cspice’ static library are ‘builtBy’ the ‘extractTar’ task. Rather than wiring the tasks together, you instead need to tell Gradle about this relationship between the ‘cspice.c’ source set and the ‘extractTar’ task.

See http://www.gradle.org/docs/current/release-notes.html#support-for-generated-sources-in-native-binary-projects for an example of how this is done. While you can do it in a more sophisticated manner, it should be as simple as:

sources {
    cspice {
        c {
            // Tell Gradle how to build these sources
            builtBy tasks.extractTar
              source {
                srcDir "$buildDir/mice/src/cspice"
                include "**/*.c"
            }
        }
    }
}

Thanks, Daz. That was the glue I was missing.

After moving the extractTar task before this reference and adding ‘assemble.dependsOn “cspiceStaticLibrary”’, the build proceeded as I hoped.