How can I specify per flavor buildType sourceSets?
Asked Answered
G

2

14

I've got 2 flavors of an app that each have their own google maps (v1) key for debug and release (meaning 4 keys total). So I'd like to know if I can specify sourceSets based on the buildType and productFlavor. Essentially, I'm wondering how I can achieve something like this:

src
├── debug
│   └── flavor1
│       └── res
│           └── values
│               └── gmaps_key.xml
├── release
│   └──flavor1
│       └── res
│           └── values
│               └── gmaps_key.xml

Where gradle will use the src/<currentBuldType>/<currentProductFlavor>/* as part of its sourceSet.

Essentially I want it so that if I run gradle assembleFlavor1Debug it will include everything under src/main/*, src/flavor1/*, and src/debug/flavor1/*.

My build.gradle is super simple:

buildscript {
    repositories {
        mavenCentral()
    }   

    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.0'
    }   
}

apply plugin: 'android'

android {
    compileSdkVersion 8

    productFlavors {
        flavor1 {
            packageName 'com.flavor1'
        }
        flavor2 {
            packageName 'com.flavor2'
        }
    }
}

Any thoughts? Or maybe a better approach to this?

Gemot answered 8/8, 2013 at 6:33 Comment(0)
G
5

For Google Maps API integration you can check my gradle sample code here : https://github.com/shakalaca/learning_gradle_android/tree/master/07_tricks

Basically do a little trick in android.applicationVariants.all during the mergeResources phase, and place the API key in strings.xml under different flaver/buildtype combination folder.

Goff answered 5/9, 2013 at 8:4 Comment(1)
I'm accepting your answer because this is very similar to how I ended up doing things.Gemot
N
19

I happened to come back to this because of a comment on my answer and realized that this answer is superfluous (still better than the accepted one which is even more so). For each productFlavor and buildType, combination and individual source sets already exist. i.e. src/{buildType}, src/{productFlavor} and src/{productFlavor}{buildType} are already available source folders.

So essentially, all that was needed for the OP was to put the resources in src/flavor1Debug which is equivalent to the src/debug/flavor1 that the OP envisions.

OLD ANSWER: I've done something similar with buildConfig but hopefully it should work with sourceSets.

Basically, you define the common stuff at the productFlavors level in a variable and keep adding things as you move down.

productFlavors {
        def common = 'src/main'

        flavor1 {
            def flavor = 'src/main/flavor1'
            buildTypes {
                debug {
                    sourceSets {
                        res.srcDirs = [ common + ',' + flavor + ',' + 'src/main/debug'
                    }
                }

                release {
                    sourceSets {
                        res.srcDirs = [ common + ',' + flavor + ',' + 'src/main/release'
                    }

            }
        }
}

I haven't tested this. I think you might need to use android.sourceSets instead of just sourceSets.

I've also needed to define separate resources for the productFlavors so I used a separate statement late in the build file. Like so:

android.sourceSets.flavor1 {
    res.srcDirs = ['flavor_resources/flavor1/res']
}

You should just be able to use android.sourceSets.flavor1.debug instead if you need to.

Also note that according to the Android Gradle user guide, using srcDir adds the directory to the default sources and srcDirs replaces them.

Neale answered 31/8, 2013 at 4:28 Comment(3)
How would I do this dynamically? I have sourceSets.whenObjectAdded { sourceSet -> sourceSet.java.srcDirs = "someDir"} and then the source sets defined per flavor like this: sourceSets { flavor1{} flavor2{}}. I want to do something like: sourceSet.debug.java.srcDirs = "someDir" for each product flavor and per buildType.Brouhaha
I edited the answer, do you still need something more custom?Neale
Hy @saad farooq I'm aware of the solution that was edited (thank you for posting it anyways!), however my product flavors are complex and reuse resources. I might need to rethink what im doing, but the dynamic solution for me would be nicer, since I have 12 product flavors and I don't want to create additional folders like this flavor1Release, flavor1Debug, flavor1DebugFull. This would lead to a permutaion of too many folders, it's time consuming to maintain it. I posted a question also: #41590141Brouhaha
G
5

For Google Maps API integration you can check my gradle sample code here : https://github.com/shakalaca/learning_gradle_android/tree/master/07_tricks

Basically do a little trick in android.applicationVariants.all during the mergeResources phase, and place the API key in strings.xml under different flaver/buildtype combination folder.

Goff answered 5/9, 2013 at 8:4 Comment(1)
I'm accepting your answer because this is very similar to how I ended up doing things.Gemot

© 2022 - 2024 — McMap. All rights reserved.