我正在尝试让Gradle在我的多项目构建中根据我是为桌面还是为Android构建来选择不同的依赖项。我有一个共同的子项目(库),我试图重用。但是,我无法让Gradle正确切换依赖配置。
我的主settings.gradle
只包含所有依赖项:
// /settings.gradle
rootProject.name = 'myProject'
include 'androidUI'
include 'reusableLibrary'
include 'desktopUI'
现在,androidUI
和desktopUI
都将reusableLibrary
指定为依赖项:
// /androidUI/build.gradle and /desktopUI/build.gradle
apply plugin: 'java'
dependencies {
compile project(path: ':reusableLibrary', configuration: 'desktop')
}
reusableLibrary
本身指定了两种配置,因为它的依赖关系是不同的,无论它是建立在桌面还是Android上:
// /reusableLibrary/build.gradle
apply plugin: 'java'
configurations {
desktop {
extendsFrom compile
}
android {
extendsFrom compile
}
}
dependencies {
// Just examples, the real list is longer.
// The point is that h2database is only included on desktop,
// and ormlite is only included on Android.
android 'com.j256.ormlite:ormlite-jdbc:5.0'
desktop 'com.h2database:h2:1.4.192'
}
这个看起来对我来说很好。但是当我编译desktopUI
或androidUI
时,我可以看到尽管reusableLibrary
的依赖以我想要的方式包含在类路径中,由reusableLibrary
本身提供的实际JAR 包含不。这当然会导致构建失败。我怀疑我没有正确设置reusableLibrary
;我不清楚configurations {}
块做了什么。
为什么reusableLibrary
中的编译项目不包含在UI项目的类路径中?以这种方式包含特定于平台的依赖项的规范方法是什么?
答案 0 :(得分:1)
原始配置非常接近正确。关键是要从Gradle Java plugin's documentation:
了解这种依赖图这是Java插件的各种依赖关系配置的可视化,这是Gradle-ese的"依赖关系列表。"当您向compile
块添加dependencies {...}
行时,您需要将Dependency
元素添加到compile
依赖关系列表中。
default
依赖关系配置很特殊;它是compile project("path")
行所包含的行,除非使用configuration:
参数选择不同的行。这意味着在构建库时,runtime
依赖关系列表(包含库本身的已编译jar )将添加到客户端项目的类路径中。
原始配置在此图表中创建了两个新节点desktop
和android
,并使用compile
将它们耦合到extendsFrom
。它们没有以其他方式连接到图表!现在原始配置的问题是显而易见的:通过将上游项目切换到其中任何一个,它缺少来自runtime
的编译代码。这解释了类路径遗漏。
解决方案比在desktop
瞄准android
和runtime
更加微妙。为了确保在添加测试时所有内容都正确解耦,我们需要一个额外的依赖关系配置层,以使testCompile
间接依赖于runtime
。另外,库的源代码本身可能需要在类路径上进行类型检查;我们可以使用compileOnly
。最终解决方案如下所示:
configurations {
desktopCompile
androidCompile
compileOnly.extendsFrom desktopCompile
testCompile.extendsFrom desktopCompile // Assuming tests run on the desktop
desktop {
extendsFrom desktopCompile
extendsFrom runtime
}
android {
extendsFrom androidCompile
extendsFrom runtime
}
}
dependencies {
androidCompile "some.android:dependency"
desktopCompile "other.desktop:dependency"
}