我住的結構是基於將類似的項目分成子項目結構。
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
配置過程中的每個項目組配置本身知道settings.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}"
}
搖籃建立文件似乎留下了一堆散落周圍可能未使用的任務。我只是試圖忽略這些?
這不是創建任務的構建文件,它是在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/