社内でGradle勉強会をやりました! その時の資料です。
Gradleを使えるようになるにはドキュメント読むのが一番なんだけど、Gradle(とGroovy)を全く知らないとドキュメントがスラスラ読めない、という印象を持ってます。
私もGroovyやったことなかったし、Gradleのドキュメントを読んで理解するのに苦労しました。 なので、自分自身でドキュメントを読んで学んでいくためにおさえておくと良さそうだと思った部分を話しました。
それにしてもAndroidのおかげで社内のGradle化が捗りますねー、ありがたい!
以下スライド本文
2014/5/24 追記 スライドをmarkdownで書いてたので本文も載っけることにしました。
Gradleを使えるようになるために
目次
Gradleとは
- JVMで動くビルドツール
- ビルドスクリプトをGroovyで書く
- ライブラリの依存関係管理もできる
- Springなど、Javaのプロダクトのビルドで使われている
- Androidアプリのビルドにも使われる(今後標準になる?)
Gradleを使えるようになるにはどうすれば?
- ドキュメントを読もう!
- でも何も分からない状態だとちょっと読みづらい・・・
- 読むための知識を身につけよう!
とりあえず動かす
Gradleをダウンロードしてパスを通して実行してみる
$ gradle :help Welcome to Gradle 1.12. To run a build, run gradle... To see a list of available tasks, run gradle tasks To see a list of command-line options, run gradle --help BUILD SUCCESSFUL Total time: 2.464 secs
ビルドスクリプトはbuild.gradleにGroovyで書く
// build.gradle println("hogehoge")
build.gradleと同じディレクトリで実行してみる
$ gradle hogehoge Welcome to Gradle 1.12. To run a build, run gradle... To see a list of available tasks, run gradle tasks To see a list of command-line options, run gradle --help BUILD SUCCESSFUL Total time: 2.464 secs
build.gradleに記述した通り"hogehoge"が出力されてる!
実際は、実行したい処理は タスク として記述する
// build.gradle task hoge << { println("hogehoge") }
gradle <task name> でタスクを実行する
$ gradle hoge :hoge hogehoge BUILD SUCCESSFUL Total time: 2.694 secs
-qオプションをつけるとタスクの出力のみを表示する
$ gradle -q hoge hogehoge
タスク一覧を表示。hoge以外にも最初からいくつかある
$ gradle -q tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Build Setup tasks ----------------- init - Initializes a new Gradle build. [incubating] wrapper - Generates Gradle wrapper files. [incubating] Help tasks ---------- dependencies - Displays all dependencies declared in root project 'fuga'. dependencyInsight - Displays the insight into a specific dependency in root project 'fuga'. help - Displays a help message projects - Displays the sub-projects of root project 'fuga'. properties - Displays the properties of root project 'fuga'. tasks - Displays the tasks runnable from root project 'fuga'. Other tasks ----------- hoge To see all tasks and more detail, run with --all.
タスク同士は依存関係を持つことができる
// build.gradle task hoge << { println("hogehoge") } task fuga(dependsOn: "hoge") << { println("fugafuga") }
fugaタスクはhogeタスクに依存している
fugaタスクを実行すると、先にhogeタスクが実行される
$ gradle -q fuga hogehoge fugafuga
tasksタスクの--allオプション
タスクの依存関係も表示してくれる
$ gradle -q tasks --all ・・・ Other tasks ----------- fuga hoge
ちょっとまとめ
- build.gradleにビルドスクリプトを書く
- 処理はタスクという単位で書いたり実行したりする
- tasksタスクで(gradle tasks)実行できるタスクを確認できる
- -qオプションでタスクの出力以外を表示しない
- タスク同士は依存関係を持てる
- gradle tasks --all で依存関係を確認できる
超シンプルな例
// build.gradle apply plugin: 'java' repositories { mavenCentral() } dependencies { compile 'joda-time:joda-time:2.3' }
プラグインの設定
apply plugin: 'java'
$ gradle -q tasks Build tasks ----------- assemble - Assembles the outputs of this project. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. classes - Assembles classes 'main'. clean - Deletes the build directory. jar - Assembles a jar archive containing the main classes. testClasses - Assembles classes 'test'. # 他にもいろいろ...
ディレクトリ構成
- Javaプラグインを使うとき、以下のようなディレクトリ構成になっていることが想定されている
- カスタマイズは可能
- ユーザーガイド => Javaクイックスタート
<PROJECT_HOME> ├── build.gradle └── src ├── main │ ├── java │ │ └── myapp │ │ └── Main.java │ └── resources └── test ├── java └── resources
ライブラリの依存関係管理
// build.gradle repositories { mavenCentral() } dependencies { compile 'joda-time:joda-time:2.3' }
- repositories
- dependencies
- プロジェクトで使用するライブラリを指定する
- ユーザーガイド => 依存関係管理の基本
ちょっとまとめ
- build.scriptには、Groovyでごりごり実装していくのではなくDSLを使って設定を記述していく感じ
- プラグインを使ってタスクを追加できる
- プラグインで何ができるかはユーザーガイドで調べることができる
- GradleでJavaをビルドする場合は、デフォルトで想定されるディレクトリ構成がある
- Mavenリポジトリを使ったライブラリの依存関係管理ができる
超シンプルな例を詳しく見てみる
applyは何者?
// build.gradle apply plugin: 'java'
- Projectオブジェクトのapply()メソッド
- build.gradleではProjectオブジェクトのメソッドが呼べる
- DSLリファレンスで他のメソッドも分かる -> Project
- ただのメソッド呼び出しがGroovyのおかげで設定項目のように見える
repositoriesとdependenciesもProjectのメソッド
// build.gradle repositories { mavenCentral() } dependencies { compile 'joda-time:joda-time:2.3' }
repositories { mavenCentral() }
repositories(function(){ mavenCentral() });
じゃあmavenCentral()もProjectのメソッド?
// build.gradle
repositories {
mavenCentral()
}
- 違う
- リファレンスを見てもProjectにmavenCentral()はない
- じゃあ、誰のメソッドを呼び出しているのか?
DSLリファレンスで
repositoriesスクリプトブロックを調べる
"The RepositoryHandler is passed to the closure as the closure's delegate."
Delegates to: RepositoryHandler from repositories
[ 引用 ] Gradleビルド言語リファレンス
- クロージャ内からRepositoryHandlerにアクセスできる
- mavenCentral()メソッドは、RepositoryHandlerオブジェクトのメソッド
- DSLリファレンス -> RepositoryHandler
なぜクロージャ内からRepositoryHandlerの
メソッドを呼べるのか?
- クロージャの暗黙的引数であるdelegateを利用している
- delegate変数にRepositoryHandlerオブジェクトが渡される
- "delegate"を省略してメソッド名のみで呼ぶことができる(thisのように省略できる)。つまり、以下の2つは同じ
repositories { mavenCentral() }
repositories { delegate.mavenCentral() }
ちょっとまとめ
- build.gradleではProjectのメソッドが呼べる
- DSLリファレンスでProjectを調べれば、build.gradleに何を書けるのか分かる
- メソッドの中にはクロージャを渡せるものがあり、スクリプトブロックとなる
- ブロック内(クロージャ)では、Project以外のオブジェクトのメソッドも呼べる
- ブロック内から参照できるオブジェクトはDSLリファレンスの「Deletes to:」を見ると分かる
Androidアプリプロジェクトのビルドスクリプト
Android Studioで作成したプロジェクトを見てみよう!
Gradle関連のファイルをピックアップ
<PROJECT_HOME> |- build.gradle |- gradle/ | `- wrapper/ | |- gradle-wrapper.jar | `- gradle-wrapper.properties |- gradlew |- gradlew.bat |- settings.gradle | `- app/ `- build.gradle
gradlew, gradlew.bat, gradle/
- Gradleラッパーという仕組みがある
- ユーザーガイド => Gradleラッパー
- gradlewコマンドを実行するとgradle-wrapper.propertiesに書いてあるバージョンのGradleをダウンロードして使ってくれる
- 各環境にあるgradleコマンドを使うのではなく、プロジェクト上のgradlewを使うことで環境依存を減らせる
<PROJECT_HOME> |- gradle/ | `- wrapper/ | |- gradle-wrapper.jar | `- gradle-wrapper.properties |- gradlew `- gradlew.bat
build.gradle
<PROJECT_HOME> |- build.gradle |- settings.gradle `- app/ `- build.gradle
マルチプロジェクト
- Gradleはサブプロジェクトを持つ階層型のプロジェクト構成を定義できる
- Androidではマルチプロジェクト構成となっている
- Android開発ではライブラリプロジェクトをサブプロジェクトとして追加していくことができる
- ユーザーガイド => マルチプロジェクトのJavaビルド
settings.gradle
- マルチプロジェクト構成におけるサブプロジェクトを定義する
<PROJECT_HOME> |- build.gradle |- settings.gradle `- app/ `- build.gradle
settings.gradleの中身
// settings.gradle include ':app'
includeは何者?
build.gradle
中身を見てみよう!もう調べられるはず!
<PROJECT_HOME> |- build.gradle |- settings.gradle `- app/ `- build.gradle
ちょっとまとめ
- Gradleラッパーで環境によらず同じバージョンのGradleを使える
- Gradleではマルチプロジェクト構成にできる
- サブプロジェクトはsettings.gradleで定義
- settings.gradleではSettingsのメソッドが呼べる
- Androidアプリ開発ではマルチプロジェクト構成になる
全体のまとめ
- Gradleでは色々できる
- 何ができるかはドキュメントを読むと分かる
- だけど何も知らないとドキュメントは読みづらい
- 以下の点を知っておくと読みやすくなると思う
- Gradleにはおおまかにどんな機能があるか
- build.gradleに記述できる内容をどうやって調べるか
- 今日出てきたGradleの機能たち
- タスク
- プラグイン
- ライブラリの依存関係の管理
- マルチプロジェクト
- Gradleラッパー
- ユーザーガイドを見ると各機能について調べられる
- 標準的な各種プラグインで何ができるかもユーザーガイドを見れば分かる
- build.scriptではProjectのメソッドが呼べる
- DSLリファレンスでProjectを調べることでbuild.scriptに何を書けるか分かる
- スクリプトブロック内では、delegateされたオブジェクトのメソッドも呼べる
- マルチプロジェクト構成ではsettings.gradleも必要になる
- settings.gradleではSettingsのメソッドが呼べる