Gradle 配置多模块 android 库
Gradle configuration with multi-module android library
回溯历史
我有这个 android 库 aar
开发者可以正常使用
compile 'com.companyname.sdk:android-sdk:2.x'
现在我们正在从头开始重写库以创建 V3。
在这次重组中,我们设法将库分解为模块。所以可以说在 V3 上我们会有以下工件
compile 'com.companyname.sdk:core:3.x'
compile 'com.companyname.sdk:extra_1:3.x'
compile 'com.companyname.sdk:extra_2:3.x'
compile 'com.companyname.sdk:extra_ ....
这将在 gradle 结构上提供以下模块:
root:
|- test_app (apk just for testing, not deployed anywhere)
|- sdk (aka: core)
|- extra_1
|- extra_2
|- extra_ ... etc
他们 build.gradle
上的每个 extra
模块都有一个 provided (':sdk')
,因此可以使用 sdk
模块中的所有内容,但实际上并不在自己内部编译它。
但我还想为现有主机应用程序提供一个简单的迁移路径。意思是,我希望在 V3 上也有以下结合了 core
和 extra_1
的工件(这基本上是当前 V2 上的工件)。
compile 'com.companyname.sdk:android-sdk:3.0.0'
理论上这一切听起来不错,但我真的很难找到一个 gradle 结构来让我轻松导出所有这些。
我想达到的目标
所以我希望能够在构建过程中生成以下工件:
android-sdk
包括 core
和 extra_1
core
extra_1
- ...所有其他额外内容
我尝试了什么
添加一个名为 legacy
的额外模块,不使用任何代码应用 com.android.library
并为其他两个模块添加 compile project
。它生成一个空的 aar
添加 core/legacy buildTypes 以及来自两个模块的 sourceSets。从未生成 2 aar
添加 core/legacy productFlavours 和来自两个模块的 sourceSets。不编译,因为它找不到从 sdk
声明到 extra_1
的导入(其中一些是在注释处理器或 lombok 期间生成的)
添加 core/legacy productFlavours 和 compile project('extra_1')
。无法编译,因为 sdk 和 extra_1.
之间存在循环依赖
回答
根据 Gabrielle 的回答,我最终进行了更多挖掘,发现创建具有依赖项的额外模块的选项是正确的。它将生成一个带有空清单和空 类 的 AAR。但重要的部分是它将生成的 POM 文件,其中将包含正确的依赖项。
关于该方法的警告是关于 maven-publish
插件的配置。通常你需要一个带有 publications
的 publishing
对象和一个 pom.withXml
节点。我的情况如下:
pom.withXml {
def root = asNode()
def license = root.appendNode('licenses').appendNode('license')
license.appendNode('name', 'The Apache Software License, Version 2.0')
license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt')
license.appendNode('distribution', 'repo')
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dependency ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
该方法的问题是 dependency.version
(最后)未指定,因此它生成了一个包含 <version>unspecified</version>
.
的 POM 文件
你的解决方案很简单,用正确版本号的脚本上的一些变量替换 late 。我的看起来像:
dependencyNode.appendNode('version', "${rootProject.ext.SDK_VERSION}")
你应该这样做:
root:
|- test_app (apk just for testing, not deployed anywhere)
|- core
|- extra_1
|- extra_2
|- extra_ ... etc
|- android-sdk
在core/build.gradle
中:
apply plugin: 'com.android.library'
//...
在extra1/build.gradle
中:
apply plugin: 'com.android.library'
//...
dependencies {
compile project(':core')
}
在android-sdk/build.gradle
中:
apply plugin: 'com.android.library'
//...
dependencies {
compile project(':core')
compile project(':extra')
}
回溯历史
我有这个 android 库 aar
开发者可以正常使用
compile 'com.companyname.sdk:android-sdk:2.x'
现在我们正在从头开始重写库以创建 V3。
在这次重组中,我们设法将库分解为模块。所以可以说在 V3 上我们会有以下工件
compile 'com.companyname.sdk:core:3.x'
compile 'com.companyname.sdk:extra_1:3.x'
compile 'com.companyname.sdk:extra_2:3.x'
compile 'com.companyname.sdk:extra_ ....
这将在 gradle 结构上提供以下模块:
root:
|- test_app (apk just for testing, not deployed anywhere)
|- sdk (aka: core)
|- extra_1
|- extra_2
|- extra_ ... etc
他们 build.gradle
上的每个 extra
模块都有一个 provided (':sdk')
,因此可以使用 sdk
模块中的所有内容,但实际上并不在自己内部编译它。
但我还想为现有主机应用程序提供一个简单的迁移路径。意思是,我希望在 V3 上也有以下结合了 core
和 extra_1
的工件(这基本上是当前 V2 上的工件)。
compile 'com.companyname.sdk:android-sdk:3.0.0'
理论上这一切听起来不错,但我真的很难找到一个 gradle 结构来让我轻松导出所有这些。
我想达到的目标
所以我希望能够在构建过程中生成以下工件:
android-sdk
包括core
和extra_1
core
extra_1
- ...所有其他额外内容
我尝试了什么
添加一个名为
legacy
的额外模块,不使用任何代码应用com.android.library
并为其他两个模块添加compile project
。它生成一个空的aar
添加 core/legacy buildTypes 以及来自两个模块的 sourceSets。从未生成 2
aar
添加 core/legacy productFlavours 和来自两个模块的 sourceSets。不编译,因为它找不到从
sdk
声明到extra_1
的导入(其中一些是在注释处理器或 lombok 期间生成的)添加 core/legacy productFlavours 和
compile project('extra_1')
。无法编译,因为 sdk 和 extra_1. 之间存在循环依赖
回答
根据 Gabrielle 的回答,我最终进行了更多挖掘,发现创建具有依赖项的额外模块的选项是正确的。它将生成一个带有空清单和空 类 的 AAR。但重要的部分是它将生成的 POM 文件,其中将包含正确的依赖项。
关于该方法的警告是关于 maven-publish
插件的配置。通常你需要一个带有 publications
的 publishing
对象和一个 pom.withXml
节点。我的情况如下:
pom.withXml {
def root = asNode()
def license = root.appendNode('licenses').appendNode('license')
license.appendNode('name', 'The Apache Software License, Version 2.0')
license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt')
license.appendNode('distribution', 'repo')
def dependenciesNode = asNode().appendNode('dependencies')
configurations.compile.allDependencies.each { dependency ->
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
该方法的问题是 dependency.version
(最后)未指定,因此它生成了一个包含 <version>unspecified</version>
.
你的解决方案很简单,用正确版本号的脚本上的一些变量替换 late 。我的看起来像:
dependencyNode.appendNode('version', "${rootProject.ext.SDK_VERSION}")
你应该这样做:
root:
|- test_app (apk just for testing, not deployed anywhere)
|- core
|- extra_1
|- extra_2
|- extra_ ... etc
|- android-sdk
在core/build.gradle
中:
apply plugin: 'com.android.library'
//...
在extra1/build.gradle
中:
apply plugin: 'com.android.library'
//...
dependencies {
compile project(':core')
}
在android-sdk/build.gradle
中:
apply plugin: 'com.android.library'
//...
dependencies {
compile project(':core')
compile project(':extra')
}