Search code examples
gradlegroovybuild.gradlemulti-project

How to diagnose / troubleshoot gradle build not running dependency task?


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?

build.gradle of parent project

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

build.gradle of subproject 'cppproj'

apply plugin: "cpp"

model {
    components {
        api(NativeLibrarySpec) {
            sources {
                // ...
            }
        }
    }
}

-


Related questions

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.


Solution

  • 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.