22

Just like the example here I am extending my build types to add staging:

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

But I also have a dependency:

implementation project(':mylibrary')

Compilation fails because it doesn't know what to pair staging to in :mylibrary:

* What went wrong:
Could not determine the dependencies of task ':app:compileStagingJavaWithJavac'.
> Could not resolve all task dependencies for configuration ':app:stagingCompileClasspath'.
   > Could not resolve project :mylibrary.
     Required by:
         project :app
      > Unable to find a matching configuration of project :mylibrary:
          - Configuration 'debugApiElements':
              - Required com.android.build.api.attributes.BuildTypeAttr 'staging' and found incompatible value 'debug'.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but wasn't required.
              - Required org.gradle.api.attributes.Usage 'java-api' and found compatible value 'java-api'.
          - Configuration 'debugRuntimeElements':
              - Required com.android.build.api.attributes.BuildTypeAttr 'staging' and found incompatible value 'debug'.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but wasn't required.
              - Required org.gradle.api.attributes.Usage 'java-api' and found incompatible value 'java-runtime'.
          - Configuration 'releaseApiElements':
              - Required com.android.build.api.attributes.BuildTypeAttr 'staging' and found incompatible value 'release'.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but wasn't required.
              - Required org.gradle.api.attributes.Usage 'java-api' and found compatible value 'java-api'.
          - Configuration 'releaseRuntimeElements':
              - Required com.android.build.api.attributes.BuildTypeAttr 'staging' and found incompatible value 'release'.
              - Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
              - Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but wasn't required.
              - Required org.gradle.api.attributes.Usage 'java-api' and found incompatible value 'java-runtime'.

That's fair enough, but I cannot go through all of my libraries adding staging just to get a different application suffix.

I tried:

debugImplementation project(path: ':mylibrary', configuration: 'debug')
releaseImplementation project(path: ':mylibrary', configuration: 'release')
stagingImplementation project(path: ':mylibrary', configuration: 'release')

But it fails:

* What went wrong:
Could not determine the dependencies of task ':app:compileReleaseJavaWithJavac'.
> Could not resolve all task dependencies for configuration ':app:releaseCompileClasspath'.
   > Could not resolve project :mylibrary.
     Required by:
         project :app
      > Project :app declares a dependency from configuration 'releaseImplementation' to configuration 'release' which is not declared in the descriptor for project :mylibrary.

debugImplementation project(path: ':mylibrary', configuration: 'default')
releaseImplementation project(path: ':mylibrary', configuration: 'default')
stagingImplementation project(path: ':mylibrary', configuration: 'default')

This works but every build has release build of library. I don't want that, I need debug to have debug version of library.

I've seen this q, but it's pre "implementation" and publishNonDefault true had no effect, same error as above.

publishNonDefault is deprecated and has no effect anymore. All variants are now published.

Gradlew version 4.6

weston
  • 54,145
  • 21
  • 145
  • 203
  • `I cannot go through all of my libraries adding staging just to get a different application suffix.` Maybe you should, OR follow another structure one lib contain all libs that belong to realease version and another contain all libs that belong to debug version, now you can go through only two libs. –  Mar 14 '18 at 20:22
  • @lbrahim Then those two libraries share the same issue as the app. i.e. they have `staging` but their dependencies do not. – weston Mar 14 '18 at 20:25
  • Their dependencies depend on their status, If the main-lib is release then the the sub-libs are. –  Mar 14 '18 at 20:27
  • @lbrahim `release` is not the issue though is it? `staging` is the pest here. When one module is building `staging`, how can it have a dependency on a project that doesn't have `staging`? – weston Mar 14 '18 at 20:29
  • The sub-libs of the main-lib e.g "staging" or whatever will implement the default flavor for the main-lib, which part not clear? –  Mar 14 '18 at 20:32
  • I recommend to read [this](https://stackoverflow.com/questions/45679847/android-studio-3-0-compile-issue-cannot-choose-between-configurations/45685318#45685318) –  Mar 14 '18 at 20:34
  • @lbrahim thanks, but seems to be all out of date. I can't go back to `debugCompile` etc. That's old stuff, replaced by `implementation` as you know. – weston Mar 14 '18 at 20:43
  • @lbrahim the two submodule idea. I can't see that working, for the same reason as the app doesn't work. But if you can make a quick example in an answer I'll give it a shot. – weston Mar 14 '18 at 20:55

2 Answers2

51

Been here, done that :P

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 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.

weston
  • 54,145
  • 21
  • 145
  • 203
ahasbini
  • 6,761
  • 2
  • 29
  • 45
  • If this work with *main-projects* and *sub-projects* then it would be perfect one. –  Mar 14 '18 at 22:12
  • It only needs to be set in the `build.gradle` of the module that depends on the library modules that don't have the said module's build types such as `staging` in this case – ahasbini Mar 14 '18 at 22:13
  • 1
    Thanks so much that really did the trick. I'm just going to edit answer to the minimum I had to do. I only had to specify where it was a non-standard build type. – weston Mar 14 '18 at 22:19
  • 1
    You may want to add a new answer to this question: https://stackoverflow.com/questions/28081846/use-different-build-types-of-library-module-in-android-app-module-in-android-stu – weston Mar 14 '18 at 22:22
  • 4
    +50 because you saved me a bunch of time and hair! – weston Mar 20 '18 at 14:05
  • Thanks and happy to help :D – ahasbini Mar 20 '18 at 14:20
0

I was creating a staging buildType in my react native project too, the build was fine, but for some reason it was loading an old version of the app.

If your react native is loading a old version:

Try the following changes at /android/app/build.gradle file:

1. Change the buildType name from staging to releaseStaging

I don't know the reason yet. But this is the main change that made my react native app open the correct version of the app.

buildTypes {
    ...
    releaseStaging {
        initWith release
        ...
    }
}

2. Include the matchingFallbacks = ['release'], just like @ahasbini mentioned.

This fixed some build errors.

buildTypes {
    ...
    releaseStaging {
        initWith release
        matchingFallbacks = ['release']
        ...
    }
}

3. If you have hermes enabled, you should include a releaseStagingImplementation, just like the code below.

After including this, my app stopped to crash while starting.

if (enableHermes) {
    def hermesPath = "../../node_modules/hermes-engine/android/";
    debugImplementation files(hermesPath + "hermes-debug.aar")
    releaseImplementation files(hermesPath + "hermes-release.aar")
    releaseStagingImplementation files(hermesPath + "hermes-release.aar")
} else {
    implementation jscFlavor
}
leonardomdr
  • 169
  • 6