简体   繁体   English

Gradle:如何实际使用自定义依赖项配置或将外部依赖项交换为本地依赖项?

[英]Gradle: How do I actually use a custom dependency configuration OR swap external dependencies for local ones?

Question

In Gradle, given a custom dependency configuration, what's the simplest way to actually use/compile with it in Android? 在Gradle中,给定自定义的依赖项配置,在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 (ie 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: 我在最顶层的项目中创建了以下build.gradle文件:

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. localProjects配置正常运行,并且每个配置都已成功地用本地项目替换了现有的依赖项(例如“ com.mycompany:utils:1.0.0”和“ com.mycompany:models:1.0.0”)。 The only problem is I can't figure out how to get Android to use the 'localProjects' dependency set instead of the 'compile' one. 唯一的问题是我不知道如何让Android使用“ localProjects”依赖集而不是“编译”依赖集。

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. 在纯Java示例中,我已经看到人们手动替换sourceSet中的类路径,但这对于Android插件来说并不容易。

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? 您如何将Android版本指向自定义依赖项配置,使其使用这些依赖项而不是compiledebugCompilereleaseCompile的依赖项进行构建?

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 (ie no more building in 3 or 4 places just to produce an APK with 'the latest') 这些更改会在构建一次后立即显示在应用程序中(即不再在3个或4个地方构建新建筑物,只是为了生成带有“最新”的APK)
  • 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 当我对这些项目中的任何一个进行代码更改时,我所要做的就是从聚合器项目中运行构建,并进行正确的编译,生成的APK反映了我计算机上的最新代码。
  • 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. 这是一个非常常见的用例,Gradle团队提到了将来会为这种事情增加更好的支持。 In the meantime, how do we solve this? 同时,我们该如何解决?

You can't really do it this way - subprojects will be affected by your "aggregator project". 您无法真正做到这一点-子项目受到“聚合器项目”的影响。 What you can do instead is to make it configurable whether a particular dependency is resolved internally or externally (both for subproject builds and the overall build). 相反,您可以做的是使它成为可配置的,而不管是在内部还是在外部(对子项目构建和整个构建而言)都解决特定的依赖关系。 See https://github.com/pniederw/elastic-deps for a proof-of-concept. 有关概念证明,请参见https://github.com/pniederw/elastic-deps

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM