2

Question

In Gradle, given a custom dependency configuration, what's the simplest way to actually use/compile with it in Android? Alternatively, what's the best way to switch between 'local' and 'external' dependencies?

Problem

To make building easier and to make better use of multi-project builds, I've created a top-level "aggregator" project that others may or may not use. So any modifications to subprojects must be self-contained in the aggregator.

In the build process for this aggregator, I want to always use local versions of the subprojects (i.e. the source code I'm editing), rather than the compiled artifacts in our repository. Additionally, this aggregator will be used in our continuous integration environment, such that the unit tests of all subprojects are run on each code commit.

Details : partial solution

Given a flat folder structure similar to the following, where all projects/modules are decoupled such that children don't know anything about parents.

+ Parent Aggregator Project
|---- build.gradle
|---- settings.gradle
|   + app                  
|   |---- build.gradle
|   + models               
|   |---- build.gradle
|   + networking           
|   |---- build.gradle
|   + utils                
|   |---- build.gradle

I've created the following build.gradle file in the top-most project:

allprojects {
    configurations {
        localProjects {
            extendsFrom compile
        }
    }
}

project(':app') {
    dependencies {
        localProjects project(':models')
        localProjects project(':networking')
    }
}

project(':networking') {
    dependencies {
        localProjects project(':utils')
    }
}

The localProjects configurations are working properly and each has successfully replaced the existing dependencies (like 'com.mycompany:utils:1.0.0' and 'com.mycompany:models:1.0.0') with local projects. The only problem is I can't figure out how to get Android to use the 'localProjects' dependency set instead of the 'compile' one.

In pure java examples, I've seen people manually replace the classpath in the sourceSet but this doesn't work easily for the Android plugin.

Summary

How do you point an Android build to a custom dependency configuration such that it builds with those dependencies instead of the compile, debugCompile, releaseCompile ones?

Ultimately, I just want incremental builds to work. For example, if I edit the 'models' source code then:

  • The next time I build the app, it recompiles the 'models' project
  • It does not recompile the 'networking' or 'utils' code
  • These changes show up in the app, immediately, after building once (i.e. no more building in 3 or 4 places just to produce an APK with 'the latest')
  • As I make code changes to any of these projects, all I ever have to do is run the build from the aggregator project and the right things compile and the APK that's produced reflects the latest code on my machine
  • Similarly, I can run all unit tests just from the aggregator
  • Last but not least, I cannot edit the existing projects to accomplish this. All changes must be self-contained in the aggregator because there are other engineers on the project who may not choose to use it.

This is a very common use case and the Gradle team has mentioned adding better support for this kind of thing in the future. In the meantime, how do we solve this?

4

1 回答 1

1

你不能这样做——子项目受到你的“聚合器项目”的影响。相反,您可以做的是使其可配置,无论特定依赖项是在内部还是外部解决(对于子项目构建和整体构建)。有关概念验证,请参阅https://github.com/pniederw/elastic-deps

于 2013-10-11T20:16:03.387 回答