I'm adding gradle
to a multi-project build and hitting the learning curve.
I need to invoke a custom task of type:Exec
before compilation of a subproject. The task is not invoked. Why?
task precompiletask(type:Exec) {
println "Executing pre-compile task"
// ...
}
task(":cppproj:build").dependsOn precompiletask
// Also tried this, same output
//project(":cppproj").task(":build").dependsOn precompiletask
// Also tried this -> error "Cannot add task 'build' as a task with that name already exists"; why on Earth would this syntax *add* the task "build"?
//project(":cppproj").task("build").dependsOn precompiletask // I also tried this
apply plugin: "cpp"
model {
components {
api(NativeLibrarySpec) {
sources {
// ...
}
}
}
}
Why do I find it so hard to debug this? I am running gradle
with the verbose-est output (gradle build --debug --warning-mode all
). The only mentions of my custom task precompiletask
are these, clustered towards the beginning of the output:
07:24:41.151 [DEBUG] [org.gradle.internal.operations.DefaultBuildOperationExecutor] Build operation 'Realize task :precompiletask' started
07:24:41.243 [DEBUG] [org.gradle.internal.operations.DefaultBuildOperationExecutor] Completing Build operation 'Realize task :precompiletask'
07:24:41.243 [DEBUG] [org.gradle.internal.operations.DefaultBuildOperationExecutor] Build operation 'Realize task :precompiletask' completed
07:24:41.249 [QUIET] [system.out] Executing pre-compile task
Why no errors related to failing to link the two tasks using dependsOn
? Since dependsOn
is clearly invoked in my code I'd expect an error that either the subproject or tasks are not found, or dependsOn itself fails somehow. Does this have to do with gradle
's flexibility of being able to refer to stuff that doesn't exist yet?
What does it mean to 'Realize task' anyway? Could not find this documented. Thanks.
You are not using the proper way to access the :cppproj:build task in your root project build: you are using project.task() methods , which is actually creating a new task.
You have several ways available to 'locate' the task you want to configure (adding the dependsOn constraint), as explained here : locating tasks
In your case you could write:
tasks.getByPath(':cppproj:build').dependsOn precompiletask
Note 1:
When using the syntax task(":cppproj:build").dependsOn precompiletask
: you create a new task named ':cppproj:build' on the root project and make it depend on precompiletask: that's why precompiletask is not executed if you execute build tasks from parent or subproject.
Note 2:
// Also tried this -> error "Cannot add task 'build' as a task with that name already exists"; why on Earth would this syntax add the task "build"? //project(":cppproj").task("build").dependsOn precompiletask
=> because the project.task(String)
method creates a task, so you are trying to add new task named build to the subproject which already have one build task.