-->

Gradle SourceSets by productFlavor and buildType

2019-05-21 14:49发布

问题:

EDIT flavors and paths:

Currently I have:

sourceSets.whenObjectAdded { 
    sourceSet -> 
    def sourceData = rootProject.ext[sourceSet.name]
    sourceSet.java.srcDirs = sourceData.javaDirRelease
}

The rootProject.ext is a file where all the productFlavor specific configuration is defined like this:

ext{
    flavor1 = [
        javaDirRelease : ['src/pathToJavaReleaseFiles']
        javaDirDebug : ['src/pathToJavaDebugFiles']
    ]
}

In the main build.gradle I also do: apply from: 'variants.gradle' which contains the above ext{} object.

The sourceSets are defined as such:

sourceSets {
   flavor1{}
}

This works but I want to do add a sourceSet specific to productFlavor and the buildType like this:

sourceSet.debug.java.srcDirs = 'src/pathToJavaDebugFiles'

Which could be defined for each product flavor and per buildType, but this doesn't work when I try to add it dynamically.

What works for me is this (thanks to this answer How can I specify per flavor buildType sourceSets?):

sourceSets {
    flavor1{
        def flavorData = rootProject.ext['flavor1']
        release {
            java.srcDirs = flavorData.javaDirRelease
        }
        debug {
            java.srcDirs = flavorData.javaDirDebug
        }
    }
}

However I would really like this to be added dynamically, so I can still preserve my configuration file intact. My build configuration is quite complex and not as simple as described here, therefore I don't need a suggestion to put the source files into a folder src/flavor1Debug because this resources are used from other productFlavors also, so this won't work.

回答1:

I think I understand. I will say first off once again that this is not a great setup and you should really look to move towards a more standard setup.

So for the solution, in order to read flavor sources dynamically, I recommend moving your ext structure to something like this:

ext {
    sources = [
        flavor1Debug : ['src/pathToJavaReleaseFiles']
        flavor1Release : ['src/pathToJavaDebugFiles']
    ]
}

This lets you read the source paths and iterate over keys and values in project.ext.sources.

Then you can find the variant by name and add sources from the array.

applicationVariants.all { variant ->
        def extraSources = project.ext.sources.get(variant.name)
        if (extraSources != null) {
            def extraSourceFiles = extraSources.collect { project.file(it) }
            def sourceSet = variant.sourceSets.find { it.name == variant.name }
            sourceSet.java.srcDir extraSourceFiles
            def dummyTask = project.task("register${variant.name}ExtraSourcesTask")
            variant.registerJavaGeneratingTask(dummyTask, extraSourceFiles)
        }
    }

The annoyance with doing this at the variant level is that you have to register the extra sources since the variant object at this point has already collected the sources from the source set and product flavors. However, I think this is probably the least invasive way to do this dynamically.