Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Gradle入門
Search
Benoît Quenaudon
August 19, 2016
Programming
1
280
Gradle入門
Benoît Quenaudon
August 19, 2016
Tweet
Share
More Decks by Benoît Quenaudon
See All by Benoît Quenaudon
36・15 Cash App
oldergod
1
210
Heuristics in Everyday Life
oldergod
1
6
Sweet Architecture
oldergod
1
400
Architecture at Scale (droidconNYC 2022)
oldergod
2
650
Managing gRPC with Wire
oldergod
2
580
Wire & Proto3
oldergod
0
90
Effective Reactive Architecture
oldergod
2
220
Wire 3 : Tackling gRPC with Kotlin
oldergod
0
1k
Server Driven UI Workflow
oldergod
2
510
Other Decks in Programming
See All in Programming
フロントエンドのmonorepo化と責務分離のリアーキテクト
kajitack
2
130
LLMは麻雀を知らなすぎるから俺が教育してやる
po3rin
3
2.2k
『リコリス・リコイル』に学ぶ!! 〜キャリア戦略における計画的偶発性理論と変わる勇気の重要性〜
wanko_it
1
570
Comparing decimals in Swift Testing
417_72ki
0
170
一人でAIプロダクトを作るための工夫 〜技術選定・開発プロセス編〜 / I want AI to work harder
rkaga
12
2.7k
LLMOpsのパフォーマンスを支える技術と現場で実践した改善
po3rin
8
960
GitHub Copilotの全体像と活用のヒント AI駆動開発の最初の一歩
74th
8
3k
#QiitaBash TDDで(自分の)開発がどう変わったか
ryosukedtomita
1
370
書き捨てではなく継続開発可能なコードをAIコーディングエージェントで書くために意識していること
shuyakinjo
1
290
The State of Fluid (2025)
s2b
0
180
【第4回】関東Kaggler会「Kaggleは執筆に役立つ」
mipypf
0
670
Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行うためのSekibanの試行錯誤 / Sekiban: Exploring Efficient Development and Deployment with Microsoft Orleans and Dapr Actor Models
tomohisa
0
180
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Visualization
eitanlees
146
16k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Practical Orchestrator
shlominoach
190
11k
Agile that works and the tools we love
rasmusluckow
329
21k
The Cost Of JavaScript in 2023
addyosmani
53
8.8k
How to Think Like a Performance Engineer
csswizardry
25
1.8k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
Transcript
入門
• 2007年: 初リリース • OS: クロスプラットフォーム • 種類: ビルドツール •
サイト: www.gradle.org • 2013年: Android に選ばれた
Gradle Tasks • Gradleはタスクベース。 ◦ タスクって?なんでもあり。 ◦ 例:javac, cp /src
/out, print `hello`… • タスク同士の依存関係有り • インプットとアウトプットの設定有り
CLI Gradle • gradle コマンド • ラッパー $~ gradle wrapper
で生成 ◦ gradlew.sh Linux/OS X ◦ gradlew.bat Windows ◦ gradle/wrapper/gradle-wrapper.properties ▪ 環境変数 ▪ Gradleバージョン ◦ gradle/wrapper/gradle-wrapper.jar
gradlew(rapper) • gradle のインストール確認 ◦ インストールされていない場合properties に従って妥当 なバージョンの gradle をダウンロードする
⇒ どの環境でも同じバージョンで実行される事は保 証できる
タスク実行 • タスク実行 ◦ 例 initというタスク:./gradlew init • タスク一覧の表示 ◦
./gradlew tasks
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義 • 宣言型(declarative)
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義 • 宣言型(declarative) • 命令はプラグインがやる
Gradle Build Scripts apply plugin: 'com.android.application' android { compileSdkVersion 21
buildToolsVersion '21.1.2' defaultConfig { versionCode 1 versionName '1.0' } buildTypes { release { minifyEnabled false } } } task hello { doLast { println 'ハローワールド!' } } • 設定ファイル:build.gradle • android プラグインを適用 • android プラグインの設定 • hello タスクを定義 • 宣言型(declarative) • 命令はプラグインがやる • 言語:Gradle DSL ◦ Groovy 拡張
• JVMのスクリプト言語 • オブジェクト指向 • 動的言語 • Java ⊆ Groovy
ほぼ
Groovy:Java Class class JavaGreeter { public void sayHello() { System.out.println("Hello
Java!"); } } JavaGreeter greeter = new JavaGreeter() greeter.sayHello() // Hello Java!
Groovy /* 動的 ⇒ 型チェックはランタイムに。 型定義も任意。*/ def foo = 6.5
// String interpolation println "foo has value: $foo" // foo has value: 6.5 println "Let's do some math. 5 + 6 = ${5 + 6}" // Let's do some math. 5 + 6 = 11
Groovy /* 型変更可能 や 型の確認もできる */ println "foo is of
type: ${foo.class} and has value: $foo" // foo is of type: java.math.BigDecimal and has value: 6.5 foo = "a string" println "foo is now of type: ${foo.class} and has value: $foo" // foo is now of type: java.lang.String and has value: a string
Groovy /* セミコロン 不要 */ def doubleIt(n) { n +
n // return 不要 } foo = 5 println "doubleIt($foo) = ${doubleIt(foo)}" // doubleIt(5) = 10 println "${doubleIt('foobar')}" // foobarfoobar
/* 関数の呼び出しに括弧不要:引数が一つ以上かつ不明でなければ */ def noArgs() { println "Called the no
args function" } def oneArg(x) { x } def twoArgs(x, y) { x + y } oneArg 500 // 括弧なし twoArgs 200, 300 // 括弧なし noArgs // エラー noArgs() // 引数ないため括弧必須 twoArgs oneArg 500, 200 // 不明でエラー twoArgs oneArg(500), 200 // 正常
Groovy:Closure /* Closure:引数や変数に渡せるメソッド(メソッドポインター) */ def foo = "カレー" def myClosure
= { println "Closureからの$foo" } myClosure() // Closureからのカレー foo = "寿司" def bar = myClosure bar() // Closureからの寿司
Groovy:Closure /* Closure に引数を渡すとき */ def doubleIt = { x
-> x + x } def applyTwice(func, arg){ func(func(arg)) } println applyTwice(doubleIt, 2) // 8 ((2 + 2) + 4)
Groovy:List ✠ Closure def myList = ["カレー", "寿司", "コカ・コーラ"] def
printItem = {item -> println "List item: $item"} myList.each(printItem) // List item: カレー // List item: 寿司 // List item: コカ・コーラ /* インライン Closure */ myList.each { println "引数のデフォルト名は it : $it" }
Groovy:Class /* java Class の sugar */ class Restaurant {
String greeting = "いらっしゃい" def printGreeting() { println "Greeting: $greeting" } } def myRestaurant = new Restaurant() myRestaurant.printGreeting() // Greeting: いらっしゃい myRestaurant.greeting = "まいどおおきに" myRestaurant.printGreeting() // Greeting: まいどおおきに
Groovy:Delegate /* closure に delegate オブジェクトを定義できる。 closure に存在しないリファレンスは delegate に対して評価される
*/ def greetingClosure = { greeting = "またおまえか" printGreeting() } greetingClosure() // greeting が not defined でエラー greetingClosure.delegate = myRestaurant greetingClosure() // Greeting: またおまえか
Groovy • まだまだある。 ⇒ Learn Groovy in Y minutes. ◦
https://learnxinyminutes.com/docs/groovy/
Gradle:タスク定義 • build.gradle 全体の delegate は project オブ ジェクトになる。 ◦
project.task("A") ⇒ task("A") ◦ task("A") ⇒ task "A" ◦ task "A" ⇒ task A
Gradle:タスク定義 // build.gradle println "Script start" task A A.description =
"タスク一覧にでる説明文" A.group = "タスク一覧のヘッダーになる" A.doLast { println "Do last" } A.doFirst { println "Do first" } A.leftShift { println "Do leftShift" } A << { println "Do crazy leftShift" } println "Script end"
Gradle:設定 closure // Configuration Closure を利用 // Gradle は変数のセッターを用意してくれるので //
description = "" も可能で description("") も可能。 // 例外:List の場合は = で値を設定するしかない task A { description "タスク一覧にでる説明文" group "タスク一覧のヘッダーになる" doLast { println "Do last" } }
Gradle Task:依存関係 • dependsOn: 自分の実行前に実行する • finalizedBy: 自分の実行後に実行する • mustRunAfter:
実行順番を設定する • shouldRunAfter: 実行順番を設定する ◦ 無視される場合もある。例:循環が発生する時とか
Gradle Task:依存関係 デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/dependencies
Typed Task • タイプ無し:ad hoc task ◦ task myTask {}
• タイプ有り:typed task ◦ コアタスクを拡張するイメージ ◦ task myTask(type: aType) {}
Typed Task 例、ファイルをコピーするタスク: task copy(type: Copy) { description 'resourceフォルダをtargetフォルダへコピーする' from
'resources' into 'target' } ※宣言的:どうやってコピーするかは関係ない。
Incremental Builds • 対応済のものはスキップする方針。 • どうやって判断する? ◦ Inputsのスナップショット ▪ 変更ある
⇒ 実行 ▪ 変更ない ⇒ Outputs確認 ◦ Outputsのスナップショット ▪ 変更ある ⇒ 実行 ▪ 変更ない ⇒ UP_TO_DATE ⇒ スキップする
Parameterised Task • 3つのパラメータ種 ◦ CLI ◦ gradle.properties ◦ プロパティ拡張
※プロパティ拡張>CLI>.properties
CLI // build.gradle task hello << { println world }
# shell ./gradlew hello -Pworld=value # value
gradle.properties // build.gradle task hello << { println world }
# ./build.properties # ~/.gradle/build.properties world = "value" # shell ./gradlew hello
プロパティ拡張 // build.gradle task hello << { println world }
// 全ドメインオブジェクトに world を追加する ext { world = "value" } # shell ./gradlew hello
Custom Task Type デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/custom-type
Custom Task Type class MyTask extends DefaultTask { String feeling
@TaskAction void myAction() { println "話寿司 は ${feeling}" } } task sushi(type: MyTask) su.feeling "好き"
Logging Levels • println = quiet • エラー時 ◦ スタックトレースはでない
◦ stacktrace ⇒ -s ◦ full-stacktrace ⇒ -S ▪ Gradleコアまででる Debug Info Warning Lifecycle Error Quiet -q デフォルト -i -d
Build Lifecycle Initialization Configuration Execution • シングルPJもマルチPJ もあるため • ビルドにどのPJが絡ま
れるかを確認して • 各PJのインスタンスを 作成 • どのタスクがあるか • 依存確認などのため • 各PJのビルドスクリプト が実行される ◦ build.gradle • タスクが生成され • 設定される • 生成されたタスクを • 依存関係に従って • 順番に実行する
Gradle Plugin • コアGradleが提供している機能が少ない • Plugin でできる事を増やす事が可能 • モジュール化がやりやすい •
build.gradle は宣言のみにできる
Gradle Plugin:Type • Script Plugin ◦ 他gradleスクリプトをインクルードするイメージ ◦ 例:apply from:
'other.gradle' • Binary Plugin ◦ Plugin インターフェースを実装したクラス ◦ 例:apply plugin: 'java'
Java Plugin • 用意されているタスク ◦ コンパイル ◦ Jar ◦ ドキュメンテーション
◦ テスト ◦ レポート
Java Build Lifecycle build check test testClasses process Test Resources
compile Test Java assemble jar classes process Resources compile Java
Java Plugin デモ タイム Yeah? https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai/tree/master/java-plugin
⇒ Java Plugin:Convention / src test java resources main java
resources / build reports classes main test build tests test-results
依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }
// 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }
// 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }
// 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }
// 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }
// 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
依存管理:Repo repositories { // ローカル flatDir { dirs 'libs' }
// 有名レポ mavenCentral() jcenter() mavenLocal() // ~/.m2/repository // url 指定、http, sftp, file:///... maven { url 'https://maven.fabric.io/public' } // 認証 ivy { url 'https://curry.yummy.com/ credentials { username 'user' password 'secret' } } }
依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照
compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照
compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照
compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照
compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照
compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
依存管理:Dep dependencies { // ファイル参照 compile files('libs/foo.jar', 'libs/bar.jar') // 他PJを参照
compile project(':someProject') // レポジトリから参照、長い版と省略 compile group: 'com.google.android', name:'android', version:'2.1.2' compile 'com.google.android:android:2.1.2' // テストビルド用 testCompile junit: 'junit:junit:4.12' }
Dependencies Report ./gradlew dependencyInsight
Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources
SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED BUILD SUCCESSFUL
Gradle:Dry Run -m $ ./gradlew -m assemble :compileJava SKIPPED :processResources
SKIPPED :classes SKIPPED :jar SKIPPED :assemble SKIPPED BUILD SUCCESSFUL
Gradle Daemon • GradleはJVM上で動くので起動に時間かかる ◦ いくつかのライブラリも必要で更にかかる • Daemonを使う事でいろいろキャッシュされる • デフォルトで無効
◦ 3.0(8月15日〜) からデフォルトで有効 • CIでは無効するのがおすすめ ◦ gradle.properties:org.gradle.daemon=false
Gradle Android Plugin ? Not today
Gradle 入門 以上
Gradle 入門:Reference • Udacity コース ◦ https://www.udacity.com/course/gradle-for-android-and-java--ud867 • Gradle ◦
http://gradle.org/ • Gradle vs Maven ◦ https://gradle.org/maven_vs_gradle/ • デモのレポジトリ ◦ https://github.dev.cybozu.co.jp/benoit/gradle-benkyokai