Gradleの処理順序は難しい。
目次
動作環境
WSL
上のUbuntu 20.04.1 LTS
にて、Gradle 7.0
で動作確認しています。
ビルドライフサイクル
Gradleの実行は大きく3つのフェーズに分かれています。 スクリプト中のどこに記述するかによって、どのフェーズで実行されるかが異なるので注意が必要です。
Gradleの実行フェーズ
フェーズ | 内容 |
---|---|
初期化フェーズ(Initialization) | プロジェクトがシングルかマルチかなどを判定し、 Projectオブジェクトを生成します。 |
設定フェーズ(Configuration) | ビルドスクリプトを実行して、Projectオブジェクトを構築していきます。 |
実行フェーズ(Execution) | コマンドラインで指定されたタスクを実際に実行します。 |
処理順序
ここでは、サンプルのビルドスクリプトで、ビルドライフサイクルで言うところの設定フェーズ
と実行フェーズ
の処理順序を見て行きます。
build.gradle
task helloA { println 'Hello 1' doLast { println 'Hello 2' } doFirst { println 'Hello 3' } println 'Hello 4' } task helloB { println 'Hello 5' doLast { println 'Hello 6' } println 'Hello 7' }
- 赤文字部分が
設定フェーズ
で、青文字部分が実行フェーズ
で実行される部分となります。設定フェーズ
部分はスクリプト実行の際に常に実行されます(起動タスクとして指定しなくても)。設定フェーズ
はタスクの設定をするためのフェーズなので、こういう挙動になっているものと思われます。
doFirst
とdoLast
で囲んだ部分が実行フェーズ
で実行されることになります(起動タスクとして指定した場合に実行されます)。設定フェーズ
ではこの部分は実行されません。
以下が、helloA
タスクとhelloB
タスクを実行した際の結果です。
実行結果
$ gradle helloA > Configure project : Hello 1 Hello 4 Hello 5 Hello 7 > Task :helloA Hello 3 Hello 2 BUILD SUCCESSFUL in 710ms 1 actionable task: 1 executed $ gradle helloB > Configure project : Hello 1 Hello 4 Hello 5 Hello 7 > Task :helloB Hello 6 BUILD SUCCESSFUL in 659ms 1 actionable task: 1 executed
- 結果を見てみると、設定フェーズ(Configure project)では、1, 4, 5, 7が、
helloA
でもhelloB
でも実行されていることが分かります。 - しかし、実行フェーズ(
Task :helloA
、Task :helloB
)では、それぞれのタスクでdoFirst
、doLast
で指定した部分のみ実行されていることが分かります。doFirst
とdoLast
を両方指定した場合は名前からもわかる通り、doFirst
の方が先に実行されます(helloA
の出力結果参照)。doFirst
やdoLast
を2回以上指定した場合、後から指定した方がより最初、より最後に実行されます(doFirst
はキューの先頭にAction
を突っ込んでいて、doLast
はキューの末尾にAction
を突っ込んでいるイメージです)。