Gradleのマルチプロジェクトとは
Gradleは複数のプロジェクトをまとめて管理することができます!これをマルチプロジェクトと言います。基本的には一つのRootプロジェクトがあり、複数のサブプロジェクトがある構成になります。マルチプロジェクトによって、サブプロジェクトの特性を共通管理する事ができます。例えば依存ライブラリであったり、共通するタスクなどをまとめて管理できます。
環境
本記事のサンプルコードは以下の環境で作成しました。
- gradle version 6.2.2
- java version 1.8.0_191
なお、本記事のビルドスクリプトは言語を Kotlin にしていますが、Groovy Scrpit でも同様の機能を使用できます。
マルチプロジェクトの作成
以下の手順で作成できます。
- Rootプロジェクトディレクトリの下に、サブプロジェクトのディレクトリを作る
- 親プロジェクトの settings.gradle.ktsでinclude関数によりサブプロジェクトを定義する
以下にサンプルを載せます。
gradle-multiproject-lib-dependencies
├── api
│   └── src
│       ├── main
│       └── test
├── services
│   └── personService
│       ├── src
│       └── test
├── shared
│   └── src
│       ├── main
│       └── test
├── build.gradle.kts
└── settings.gradle.kts
rootProject.name = "gradle-multiproject-lib-dependencies"
include("api", "shared", "services:personService")
基本的には上記の設定だけで、Gradleをマルチプロジェクトとして設定できます。上記の設定の場合、以下のような構成になっています。services だけはその下にさらにサブプロジェクトを含んでいます。
- 
gradle-multiproject-lib-dependencies... ルートプロジェクト- 
api... サブプロジェクト
- 
services... サブプロジェクト- 
personService... サブプロジェクト
 
- 
- 
shared... サブプロジェクト
 
- 
共通特性の定義
ルートプロジェクトの build.gradle.kts でサブプロジェクトを含む全体の特性(プロパティやタスク)を定義できます。自身を含む全部のプロジェクトに対しては allprojects ブロックを使用します。サブプロジェクトのみを対象にするなら subprojects ブロックを使用します。以下にタスクを定義する例を示します。
allprojects {
  tasks.register("hello") {
      doLast {
        println("I'm ${this.project.name}")
      }
  }
}
このタスクを実行すると以下の出力になります。
> Task :hello
I'm gradle-multiproject-lib-dependencies
> Task :api:hello
I'm api
> Task :services:hello
I'm services
> Task :shared:hello
I'm shared
> Task :services:personService:hello
I'm personService
タスクの定義だけではなく、プロジェクトのすべての設定を行えます。例えば、以下のようにサブプロジェクト全てに共通の java のビルドを設定できます。
subprojects {
    apply(plugin = "java")
    group = "org.gradle.sample"
    version = "1.0"
    repositories {
        mavenCentral()
    }
    dependencies {
        "testImplementation"("junit:junit:4.12")
    }
}
依存関係の定義
サブプロジェクト間の依存関係を定義することにより、サブプロジェクトのビルド結果を他のサブプロジェクトで利用できるようになります。Javaのプロジェクトでは、サブプロジェクトのJarを他のサブプロジェクトで利用するといったことが可能です。
設定の仕方は dependencies ブロックで依存対象のプロジェクトを project("プロジェクト名") で指定するだけです。ビルドの順番はこの依存関係によって決定されます。つまり、依存先のプロジェクトが依存元のプロジェクトより先にビルドされます。
上記のディレクトリ構成でJavaプロジェクトの場合、以下のように設定することができます。
subprojects {
    apply(plugin = "java")
    group = "org.gradle.sample"
    version = "1.0"
    repositories {
        mavenCentral()
    }
    dependencies {
        "testImplementation"("junit:junit:4.12")
    }
}
project(":api") {
    dependencies {
        "implementation"(project(":shared"))
    }
}
project(":services:personService") {
    dependencies {
        "implementation"(project(":shared"))
        "implementation"(project(":api"))
    }
}
参考
本記事では以下のサイトを参考にしました。
