Call common setup function from many build scripts

Hi,

I am new to gradle and I am trying to do one simple thing whch is call some setup closure (or apply some settings) for each project (subproject) that has Native artifacts and exhibit binaries property.

What I mean specifically is that in order to make gradle work with Visual Studio 2015 I need a workaround to add paths to Includes and Libraries of ucrt manually.

Something like:
binaries.all { if (targetPlatform.operatingSystem.windows) { cppCompiler.args "-I" + VS_2015_INCLUDE_DIR cppCompiler.args "-I" + VS_2015_INCLUDE_DIR if (targetPlatform.architecture.name == "x86") { linker.args "/LIBPATH:" + VS_2015_LIB_DIR + "/x86" } else if (targetPlatform.architecture.name == "x86-64" || targetPlatform.architecture.name == "amd64") { linker.args "/LIBPATH:" + VS_2015_LIB_DIR + "/x64" } }

where VS_2015_INCLUDE_DIR are defined accordingly.

I have to do this for each native project and its inefficient and tedious to define it in every subproject (dependency) I build from source using gradle.

How one would go about making it work with subprojects?

I tried in my master, top level, build.gradle to add something like this:

subprojects { 
  apply plugin: 'cpp'
  apply plugin: 'c'
  
  afterEvaluate {
    binaries.all { 
      if (targetPlatform.operatingSystem.windows) {
        cppCompiler.args "-I" + VS_2015_INCLUDE_DIR 
        cppCompiler.args "-I" + VS_2015_INCLUDE_DIR
        if (targetPlatform.architecture.name == "x86") {
          linker.args "/LIBPATH:" + VS_2015_LIB_DIR + "/x86"
        } 
        else if (targetPlatform.architecture.name == "x86-64" || targetPlatform.architecture.name == "amd64") {
          linker.args "/LIBPATH:" + VS_2015_LIB_DIR + "/x64"
        }
      }
    }
  }
}

But the problem is that it fails subprojects that are not native and dont have binaries (like android java project).

How can I filter that out, or maybe there is better approach to achieve what I try ? Thanks in advance

I also tried defining a closure that did the same thing and took parameters from within binaries.all { } block in each subproject but it failed the lookup so I am guessing I was missing something obvious with that approach.

You can use

plugins.withId("cpp") {
  //code to apply when cpp plugin is present
}

Thanks for suggestion, I tried to do the following but obviously I am still doing something wrong:

subprojects {
    plugins.withId("cpp") {
        model {
            binaries {
                all {
                    if (targetPlatform.operatingSystem.windows) {
                        cppCompiler.args "-I" + VS_2015_INCLUDE_DIR 
                        cppCompiler.args "-I" + VS_2015_INCLUDE_DIR
                        if (targetPlatform.architecture.name == "x86") {
                            linker.args "/LIBPATH:" + VS_2015_LIB_DIR + "/x86"
                        }
                        else if (targetPlatform.architecture.name == "x86-64" || targetPlatform.architecture.name == "amd64") {
                            linker.args "/LIBPATH:" + VS_2015_LIB_DIR + "/x64"
                        }
                    }
                }
            }
        }
    }
}

But I get the error:

  • What went wrong:
    Could not determine the dependencies of task ‘:main:installMainX64ReleaseExecutable’.

No model node at ‘repositories’

I also tried a couple other combinations non worked. I assume I am missing something obvious. When I define build files for particular subprojects I define them in components (like NativeLibrarySpec NativeExecutableSpec etc.) so I guess I cannot set binaries { all {} } on a model but I also dont know how to apply that for every Native component either.

Sorry for all the fuss.

Your last snippet is missing an afterEvaluate:

subprojects {//for all subprojects
    plugins.withId("cpp") {//if they apply the cpp plugin
        afterEvaluate {//after the user has configured the target platform
            model {//do your changes
...