我想建立一个大型项目,我被告知 gradle 是这样做的方法。
我对 Gradle 感到很困惑,整个系统似乎有很多魔法,挥手,知识,我不想阅读 Gradle 指南的所有 60 章来 grok。
我将最终得到以下组件:
我希望能够一次构建和测试所有内容。所以通常我会像这样构建一棵树:
project/ proto/
lib1/ java/ src/
test/
python/ src/
test/
...
lib2/ java/ src/
test/
python/ src/
test/
...
app1/ java/ src/
test/
python/ src/
test/
...
app2/ java/ src/
test/
python/ src/
test/
...
android/ src/
test/
iOS/ src/
test/
我知道从 gradle 构建 iOS 可能是不可能的,所以我很高兴暂时忽略它。
这是一个合适的结构吗?如何构建和放置我的 gradle.build 文件,以便其他团队可以正确使用库?我如何确保我的依赖关系紧密,以便库只包含它们需要包含的最小集合?
Gradle 构建文件似乎留下了一堆可能未使用的任务。我只是试图忽略这些吗?
最佳答案
我居住的结构是基于将类似项目分组为子项目结构。
project/client/core/common-android
project/client/core/features-android
project/client/core/ui-android
project/client/app/client-android
project/server/admin
project/server/base
project/server/util
project/server/api-deployment
project/bundles/bundle1
project/bundles/bundle2
project/bundles/bundle3
project/bundles/bundle4
这种结构使得使用子项目比平面目录结构更直观。现在我们可以将配置应用于类似的子项目。我的最终项目结构如下所示
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'platform'
+--- Project ':client' - Client: Android core projects
| +--- Project ':client:common-android' - Client: Common library for Android aar
| +--- Project ':client:features-android' - Client: Features library for Android aar
| +--- Project ':client:ui-android' - Client: UI library for Android aar
| +--- Project ':client:app-android' - Client: Apk client Android apk
+--- Project ':bundles' - bundles: OSGi bundles container project
| +--- Project ':bundles:bundle1' - bundles: OSGi bundle jar
| +--- Project ':bundles:bundle2' - bundles: OSGi bundle jar
| +--- Project ':bundles:bundle3' - bundles: OSGi bundle jar
| +--- Project ':bundles:bundle4' - bundles: OSGi bundle jar
\--- Project ':server' - Server: Coriolis root project
+--- Project ':server:admin' - Server: admin jar
+--- Project ':server:base' - Server: jar base
+--- Project ':server:apiDeployment' - Server: platform deployment war
\--- Project ':server:util' - Server: utils jar
由于我们不希望父项目尽可能少地了解他们的子项目,我们可以让每个项目分组在配置期间通过
settings.gradle
进行配置。设置.gradle:
rootProject.name = 'platform'
Map<String, String> projectProperties = startParameter.getProjectProperties()
projectProperties.put('platform', true.toString())
// TODO: Make project imports smarter by removing hardcoding of paths
def subprojects = settingsDir.listFiles(new FileFilter() {
@Override
boolean accept(File file) {
return file.isDirectory() && (file.name == 'client' || file.name == 'server')
}
})
for (File file : subprojects) {
println "Found subproject directory: $file.absolutePath"
switch (file.name) {
case 'client':
def androidHome = 'ANDROID_HOME'
// any non-null value will add android modules to the build.
// Assumption is only a valid SDK location will be set.
if (System.getenv(androidHome)) {
def clientFile = new File("$file.absolutePath/core/childProjectSettings.gradle")
if (clientFile.exists()) {
println "Adding android client"
include ':client'
project(":client").projectDir = clientFile.parentFile
apply from: clientFile.absolutePath
}
} else {
println "WARNING: Environment variable {$androidHome} not set. Not adding Android modules as they are " +
"impossible to build without the Android SDK being installed. To install the Android SDK " +
"please see: http://developer.android.com/sdk/installing/index.html"
}
break
case 'server':
def serverFile = new File("$file.absolutePath/server/childProjectSettings.gradle")
if (serverFile.exists()) {
println "Adding server"
include ':server'
project(':server').projectDir = serverFile.parentFile
apply from: serverFile.absolutePath
}
def bundlesFile = new File("$file.absolutePath/bundles/childProjectSettings.gradle")
if (bundlesFile.exists() && !projectProperties.containsKey('noBundles')) {
println "Adding osgi bundles"
include ':bundles'
project(':bundles').projectDir = bundlesFile.parentFile
apply from: bundlesFile.absolutePath
}
break
default:
println "Unknown subproject found: $file.absolutePath"
}
}
现在只包含磁盘上存在的子项目,我们可以删除剩余的硬编码以获得更动态的示例,但这更简单。然后我们创建一个文件(在本例中)
childProjectSettings.gradle
对于我们的每个项目分组(客户端、服务器、捆绑包)。您的 childProjectSettings.gradle
应该以不需要每次添加新子项目时都更新的方式指定它的子项目。childProjectSettings.gradle:
File moduleSettingsDir = new File("$settingsDir.absolutePath/server", "bundles")
println "Bundles sees settings dir as: $moduleSettingsDir.absolutePath"
def bundleDirectories = moduleSettingsDir.listFiles(new FileFilter() {
@Override
boolean accept(File pathname) {
return pathname.isDirectory()
}
})
// get a reference to this project's descriptor so we can add subprojects
ProjectDescriptor bundles = project(':bundles')
bundleDirectories.each { File bundleDir ->
if (new File(bundleDir, "build.gradle").exists()) {
// normalize project names (blah-blah -> blahBlah)
def bundleName = bundleDir.name
if (bundleName.contains("-")) {
def names = bundleDir.name.split("-")
bundleName = names[0] + names[1].capitalize()
}
// include a subproject in the build
include ":bundles:$bundleName"
// default location will be wrong lets update the project's directory
project(":bundles:$bundleName").projectDir = bundleDir
// add the project as a subproject giving us better grouping
bundles.children.add(project(":bundles:$bundleName"))
}
}
project(':bundles').children.each {
println "Parent {$it.parent} found child {$it} in path {$it.path} using buildScript {$it.buildFile $it.path}"
}
Gradle build files seem to leave a bunch of potentially unused tasks littered around. Do I just try to ignore these?
创建任务的不是构建文件,而是在
build.gradle
中应用的插件。文件。为了使任务尽可能紧凑,请仅在 build.gradle
中声明插件。它实际上已被使用。任务不是从依赖项目继承的,但声明的依赖是从依赖项目继承的。*这里有一个重要说明,所有依赖项都是
transitive
默认情况下,如果 ui
取决于 core
声明 gson
然后依赖 ui
默认有 gson
在它的类路径中。对于你关于源文件夹的问题,一个更 gradle 的结构可能看起来更像下面。您的应用程序组在哪里
lib1:java|lib1:python|lib2:java|lib2:python|app1:java|app1:python|app2:java|app2:python
每一篇论文都将是其包含小组的一个子项目。然后
lib1
项目包含两个子项目lib1:java
和 lib1:python
每个都用自己的插件编译 build.gradle
文件。通用代码可以放在 buildSrc
中的自定义插件中如果需要的话。project/ proto/
lib1/ java/ src/main/java/
src/main/javaTest/
python/ src/main/python/
src/main/pythonTest/
...
lib2/ java/ src/main/java/
src/main/javaTest/
python/ src/main/python/
src/main/pythonTest/
...
app1/ java/ src/main/java/
src/main/javaTest/
python/ src/main/python/
src/main/pythonTest/
...
app2/ java/ src/main/java/
src/main/javaTest/
python/ src/main/python/
src/main/pythonTest/
...
android/ src/
test/
iOS/ src/
test/
关于java - Gradle Build 的规范设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37147407/