Gradle dependencies between normal tasks and native generated tasks

Hi all.

I am using gradle 2.13.

I am trying to figure how the native dependencies are supposed to work. I have 4 project tasks that have dependencies like this .

  1. task1 generates cpp source for the lib
  2. task 2 compiles the sources from task 1 using gradle model/components provided by the cpp plugin
  3. task 3 generates more sources
  4. task 4 compiles the sources from task 3 using gradle model/components provided by the cpp plugin

I need to make sure the compilation happens in this order exactly : 1,2,3,4
I can’t make task 2 config phase to wait until task 3 is executed to start the config phase
I can’t make task 3 execution phase to wait until task 2 is executed
I can’t make the task 4 config phase to wait until task 3 is generated

The issue is corroborated by the fact that native compile and link tasks do not exist at during the configuration phase (until vary late). It will be nice if all the compile tasks depended on a single nativeAssemble task that exist from the beginning so i can hook nativeAssemble task to dependent on something that is build somewhere else

The hack way i found was to make a task that generates all the sources at once and do everything in 2 steps like :
$> grale genSources
$> gradle build

I am wondering if there is a way to make this hack disapear so that i only execute “gradle build” once and the dependencies are figured automatically.

Regards

I think what you are asking for is this:


// Your generator tasks
task myGenerator1 
task myGenerator3  {
  mustRunAfter myGenerator1 // can only run if Generator 1 already ran
}


model {
    components {
        myCompile2(NativeLibrarySpec) {
            sources {
                c {
                    generatedBy tasks.myGenerator1
                }
            }
        }
        myCompile3(NativeLibrarySpec) {
            sources {
                c {
                    generatedBy tasks.myGenerator2
                }
            }
       }
  }
}

// This can probably be written better, just the first thing that came to mind.
tasks.whenAdded { task ->
  if (task instance of CCompile)  { // adjust accoridng whether C or C++
    if(task.name.startsWith('myCompile4)) {
      mustRunAfter 'myGenerator1' 
      dependsOn 'myGenerator2' // Can only execute if both generation jobs were done
    }
    if(task.name.startsWith('myCompile2)) {
     tasks.getByName('myGenerator3').mustRunAfter(task) // forces next generator only to run after myCompile2* 
    }
  }
}


Perfect … but i am running into a weird issue still …

  • What went wrong:
    A problem occurred configuring project ‘:mylib’.

Exception thrown while executing model rule: NativeComponentModelPlugin.Rules#configureGeneratedSourceSets
Could not find property ‘sourceDir’ on task ‘:mylib:unzipMylib’.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Here is my script

apply plugin: “cpp”

task unzipMylib(type: Copy) {
into file(mylibSrcDir)
from zipTree(file(“libs/${mylibVersion}.zip”))
}

sharedModel()

model {

//noinspection GroovyAssignabilityCheck
components {
    mylib(NativeLibrarySpec) {
        targetPlatform "x64"
        sources {
            cpp {
                generatedBy tasks.unzipMylib

                exportedHeaders {
                    srcDir "${mylibSrcDir}/${mylibVersion}"
                }
                source {
                    srcDir "${mylibSrcDir}/${mylibVersion}"
                    include "client_bw.cpp"
                    include "cpucounters.cpp"
                    include "msr.cpp"
                    include "pci.cpp"
                }
            }
        }

    }

}

}

/*
shared model closure definition. This is the only way i could share things between projects
Not sure if it is causing issues
*/

    ext.sharedModel = {

        model {

            buildTypes {
                debug
                //release
            }

            platforms {
                x64 {
                    architecture "x86_64"
                }
            }

            binaries {
                all {

                    if (buildType == buildTypes.debug) {
                        cppCompiler.args "-g"
                    }

                    if (toolChain in Gcc) {
                        linker.args "-lrt"
                        linker.args "-lpthread"

                        cppCompiler.args "-Wall"
                        cppCompiler.args "-std=c++0x"
                        cppCompiler.args "-fPIC", "-O3"
                        cppCompiler.args "-Wno-unknown-pragmas"
                    }

                }
            }

        }

    }

Oh right, I forgot to tell you about that. You need to add an extension to your unpack task

task unzipMylib(type: Copy) {
  ext {
      sourceDir =  {file(mylibSrcDir)}
      headerDir = sourceDir
  }

    into file(mylibSrcDir)
    from zipTree(file("libs/${mylibVersion}.zip"))
}

It is becasue the generatedBy expects to methods on the generating task called getSourceDir and getHeaderDir.

That worked … thank you so much !!!

One thing i noticed is that you cannot mix the java and cpp plugins in the same gradle file apparently. It does not like mixing the model somehow[1]. Is it something that is supported ? I have to jump through some gymnastics to make this run but it still runs … thanks again !

[1]
as i have shown above i have a sharedModel closure between all the projects. And when i mix java and cpp plugin it complains about this part :
if (buildType == buildTypes.debug) {
cppCompiler.args “-g”
}

I’ve never tried mxing new model java & cpp. All I know is the new model Java is still very much in incubating (at 2.13). It would be worth creatign a separate discussion for that problme you are seeing.

The reason it’s complaining is because you are trying to access method on a Java binary that doesn’t exist. The action closure assignes to all assume all binaries will be treated the same. That include native and Java as well as any other binary that may appear in the future. Using withType(NativeBinarySpec) instead of all will most likely fix the problem. This is one of the ways to fix this failure.

perfect … thank you so much guys !!!

Regards