I have this task definition in a cpp native binaries model with a single NativeLibrarySpec component:
tasks {
export(Copy) {
from( $.components.main.sources.cpp.getExportedHeaders() ) {
into 'Include'
}
from( $.tasks.createMainReleaseStaticLibrary ) {
into 'Lib'
}
into "$projectDir"
}
}
Running this task fails with this error:
FAILURE: Build failed with an exception.
* What went wrong:
Failed to capture snapshot of output files for task 'export' during up-to-date check. See stacktrace for details.
> Failed to create MD5 hash for file C:\Users\hoobajoob\Documents\Visual Studio 2013\Projects\project-x\.gradle\2.10-rc-2
\taskArtifacts\cache.properties.lock.
…if I then change the destination from $projectDir to $buildDir or any subdirectory of the project directory like $projectDir/foo, it executes successfully.
I think the issue is that by copying into the project directory you’re marking the entire project directory as a task output.
Before executing a Copy task, Gradle will check to see if the output directory contents have changed in any way since last time the task was executed. To do this, Gradle needs to take a snapshot of the directory and store it for next time: the value is stored under $projectDir/.gradle. You can see a problem there: in creating the directory snapshot Gradle is changing the snapshot. So even if you didn’t get this exception, you’d get strange behaviour with the task never being up to date.
Bottom line is that $projectDir should never be a Task input or output. For this example, one simple way to fix it is to have 2 separate Copy tasks:
tasks {
exportInclude(Copy) {
from $.components.main.sources.cpp.getExportedHeaders()
into "$projectDir/Include"
}
exportLib(Copy) {
from $.tasks.createMainReleaseStaticLibrary
into "$projectDir/Lib"
}
}