gradle / gradle-native

The home of Gradle's support for natively compiled languages
https://blog.gradle.org/introducing-the-new-cpp-plugins
Apache License 2.0
93 stars 8 forks source link

Unable to determine if CppCompileTask is Debuggable via my configure clousure #1083

Open enaess opened 3 years ago

enaess commented 3 years ago

I am trying to configure a set of compiler flags based on a CppCompile task is debuggable or not.

Expected Behavior

I am not able to configure my CppCompile tasks given their "debuggable" status. I am keying off this as each Release and Debug configuration should have the correct 'debuggable' and 'optimized' flag set.

Current Behavior

I am seeing a race condition in which the configureEach() task of my build.gradle script is executed before the CppBasePlugin's tasks.register(.., { / this closure here gets executed last /}) routine. I believe I've set this up correctly and these configure closures are according to the Lazy API specification

I've loaded the gradle project in Intellij and stepped through with breakpoints. My closure gets executed first, it should not.

Context

I've spent a lots of time trying to solve this. Mostly trying to understand why this isn't working as per documentation. Seems like a bug to me, and I'd like to better understand how I can get a similar solution resolved while waiting for a bug-fix,

I want to configure the 'debuggable' CppCompile task with a set of additional macros like DEBUG=1, etc. Macros that are internal to our C++ build. Should be a common use-case

Steps to Reproduce (for bugs)

consider the following build.gradle file (root project)

abstract class MyTask extends DefaultTask
{
    @Input
    public abstract Property<String> getStr()

    public MyTask() {
        getStr().convention("***")
    }

    @TaskAction
    public void action() {
        println "Hello From inside task"
    }
}

configure(subprojects) { proj ->

    def mytask = proj.tasks.register("myTask", MyTask, { task ->
        task.str = "++=++"
        println "Hello from configure closure ${task.str.get()}"
    })

    proj.tasks.withType(MyTask).configureEach { task ->
        println "Hello from configureEach: ${task.str.get()}"
    }

    proj.tasks.withType(CppCompile).configureEach { task ->
        if (task.isDebuggable()) {
              macros.add("DEBUG", "1")
        }
        println "${task.name} - ${task.isDebuggable()}"
    }
}

And I've added a settings.gradle file which includes two sub-projects:

include "projA"
include "projB"

Each is a project that contains a dummy 'cpp-application' project, and a dummy src/main/cpp/main.cpp file.

The "DEBUG=1" is never set for the project, and after troubleshooting this I've found that the closure for configuring each CppCompile task here is executed before the closure in CppBasePlugin.java which registers the CppCompile task lazily.

While the example MyTask does correctly print out the closure from registration first, then the closure under configureEach(), the configureEach for CppCompile does not which cause a race in setting debuggable in CppBasePlugin and getting the debuggable flag in the additional configureEach closure.

Looking at the build scan, the task deferral seems to work just fine. No task is created prematurely, and I can't for the sake of me figure out a suitable "patch" for this problem.

Anyone able to suggest a workaround, or help fix the issue in Gradle?

Your Environment