17

Suppose I have an Android app with three build types:

buildTypes {
    release {
        ....
    }
    optRelease {
        ....
    }
    debug {
        ....
    }
}

And I have a dependent module:

dependencies {
    implementation project(':myDependency')
}

Suppose this dependency only has two build types (let's say debug and release), and I want full control over which of my app's build types uses which of the dependency's build types. For example, I'd like my app's optRelease to use the library's release, and the app's release the use the library's debug.

That used to be possible before Android Studio 3.0, but the new build variant system doesn't seem to allow for that anymore.

How can I explicitly state which build type to use? Let's say that I have no control over the dependency and cannot modify its gradle configuration.

EboMike
  • 76,846
  • 14
  • 164
  • 167

5 Answers5

13

You can use matchingFallback

buildTypes {
    release {
       matchingFallbacks = ['debug']
       ... 
    }
    optRelease {
       matchingFallbacks = ['release']  
       ...
    }
    debug {
       matchingFallbacks = ['debug']  
       ...
    }
}

You can also specify list of fallback as follows:

optRelease {
    matchingFallbacks = ['release','debug']  
}

This will specify a sorted list of fallback build types that the plugin should try to use when a dependency does not include a "optRelease" build type. You may specify as many fallbacks as you like, and the plugin selects the first build type that's available in the dependency.

You can refer to official document for more details.

However if you want to use variant-specific configurations when targeting external dependencies. You can do it as follows:

debugImplementation project(':myDependency')

This will make myDependency as a dependency to only the "debug" version of your module.

Sagar
  • 23,903
  • 4
  • 62
  • 62
  • 1
    Thanks. However, I'm looking for a way to target a specific target for a specific dependency. For example, there may be one dependency that I'd like to use "debug" for even in my own "release" build target, like for debugging reasons. This can't be done with the matchingFallbacks method. – EboMike Jun 23 '18 at 07:11
  • Hi @EboMike! Did you managed to archive this? Make a `release` build depend on a `debug` dependency – gmazzo Mar 17 '20 at 14:08
4

Thanks a lot ahasbini for your solution. Copying ahasbini's answer from this thread for easy reference to the solution.

You'll need to specify matchingFallback with the Android Gradle Plugin 3.0.0 for the plugin to know which fallback build type of library to use when being compiled with app code in case a certain build type defined in your app is not found in the library.

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        applicationIdSuffix '.debug'
    }
    staging {
        initWith release
        applicationIdSuffix '.staging'
        matchingFallbacks = ['release']
    }
}

More info here: Migrate to Android Plugin for Gradle 3.0.0.

ahasbini
  • 6,761
  • 2
  • 29
  • 45
Mohit Ajwani
  • 1,328
  • 12
  • 24
  • 1
    Thanks. However, I'm looking for a way to target a specific target for a specific dependency. For example, there may be one dependency that I'd like to use "debug" for even in my own "release" build target, like for debugging reasons. This can't be done with the matchingFallbacks method. – EboMike Jun 23 '18 at 07:11
2

If you want to add a dependency for a variant that combines a product flavor and a build type, then you must initialize the configuration name in the configurations block.(如果想为自定义的buildTypes来添加dependencies,需要配置configurations {})

android {
    buildTypes {
        release {
            ....
        }
        optRelease {
            ....
        }
        debug {
            ....
        }
    }
}

configurations {
    // Initializes a placeholder for the optReleaseImplementation dependency configuration
    optReleaseImplementation {}
}

dependencies {
        debugImplementation xxx
        // Then it can work
        optReleaseImplementation xxx
        releaseImplementation xxx
    }
zhy
  • 17
  • 2
0

Starting from gradle 3.0.0 you can use following for default project variants (release, debug, test etc)

  • implementation
  • releaseImplementation
  • testImplementation
  • debugImplementation
  • androidTestImplementation

Simple example would be:

android {
   ....
}
dependencies {
    implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
    androidTestImplementation jUnit
    testImplementation mockito
}

If you have multiple flavors of your app, starting from 3.0 you have to declare flavor dimensions first, define fallback and matching strategy in your default config (for remote dependencies, and dependencies without dimensions) and gradle will recognize what dependencies should be included for that flavor. For more info check this migration guide.

Lars
  • 710
  • 5
  • 19
Ivan Milisavljevic
  • 2,048
  • 2
  • 13
  • 21
  • I thought this syntax no longer works in Android Studio 3.0? I just tried it locally, and it doesn't work (i.e. it doesn't know what ":dependencyFlavorBuildtype" is). – EboMike Jun 15 '18 at 06:27
  • Thanks, I had read that guide, but that doesn't cover how to target specific targets of a dependency - you can only have global fallbacks, so if "buildType2" is missing, it uses "buildType3" instead, across all dependencies. I don't see anything to target a specific variant for a specific dependency. – EboMike Jun 16 '18 at 01:43
0

What I did is :

Created product flavors:

    android {
        flavorDimensions 'tier'
        compileSdkVersion 27
        defaultConfig {
            applicationId "com.example.sample"
            minSdkVersion 15
            targetSdkVersion 27
        }

        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                --------------
            }
            debug {
                debuggable true
            }
        }
        productFlavors {
            qc {
                applicationIdSuffix ".qc"
                dimension "tier"

            }
            production {
                applicationIdSuffix ".production"
                dimension "tier"
            }
        }
    }

Allow dependencies to choose the build types like below

dependencies { 
    qcDebugCompile project(path: ':libName', configuration: "debug") 
    qcReleaseCompile project(path: ':libName', configuration: "release") 
    productionDebugCompile project(path: ':libName', configuration: "debug") 
    productionReleaseCompile project(path: ':libName', configuration: "release") 
... 
} 

enter image description here

Rissmon Suresh
  • 13,173
  • 5
  • 29
  • 38