Now in Androidの読み解き - ビルドプラグイン
はじめに
キャッチアップがてら、以下リポジトリを読んでいて気になって調べたことを残していきます。
その前にこのリポジトリは何者?
KotlinとJetpackComposeで完全に構築されたAndroidアプリ。Androidの設計と開発のベストプラクティスに従っており、開発者にとって役立つリファレンスとなることを目的としている。とのこと。
※現在開発の初期段階にありPlayStoreではまだ利用できない。 2022年8月現在
気になったこと
まずプロジェクトを見るときはbuild.gradle
をみて、使用ライブラリやモジュールの関連を確認するようにしてます。で、早速気になったところがありました。
// app/build.gradel.kts
plugins {
id("nowinandroid.android.application")
id("nowinandroid.android.application.compose")
id("nowinandroid.android.application.jacoco")
kotlin("kapt")
id("jacoco")
id("dagger.hilt.android.plugin")
id("nowinandroid.spotless")
id("nowinandroid.firebase-perf")
}
id("nowinandroid.xxx.yyy")
まず、ここが気になりました。どのように動いて何をしているのか追ってみることにしました。
プロジェクトの構成はプロジェクトルート配下のgradle
とつくファイルのを見ていけば、何かしらわかるので見ていきました。settings.gradle.kts
にそれっぽい記述あり
settings.gradle.kts
pluginManagement {
includeBuild("build-logic") // この部分は何をしているか
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
build-logic
を取りこんでいるので、その部分を追っていきます。
build-logic/settings.gradle.kts
dependencyResolutionManagement {
...
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
include(":convention") // こちらを追う
build-logic/convention/build.gradle.kts
...
gradlePlugin {
plugins {
register("androidApplicationCompose") {
id = "nowinandroid.android.application.compose"
implementationClass = "AndroidApplicationComposeConventionPlugin"
}
register("androidApplication") {
id = "nowinandroid.android.application"
implementationClass = "AndroidApplicationConventionPlugin"
}
...
}
}
app/build.gradel.kts
で記述されていたidと同じ値が見つかりました。
id("nowinandroid.android.application")
はどのような挙動をするのかというと、implementationClass
に設定しているクラスを見てみます。
build-logic/convention/src/main/kotlin
配下にありました。
AndroidApplicationConventionPlugin
class AndroidApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.application")
apply("org.jetbrains.kotlin.android")
}
extensions.configure<BaseAppModuleExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 32
}
}
}
}
internal fun Project.configureKotlinAndroid(
commonExtension: CommonExtension<*, *, *, *>,
) {
commonExtension.apply {
compileSdk = 32
defaultConfig {
minSdk = 21
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = true
}
kotlinOptions {
// Treat all Kotlin warnings as errors (disabled by default)
allWarningsAsErrors = properties["warningsAsErrors"] as? Boolean ?: false
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=kotlin.RequiresOptIn",
// Enable experimental coroutines APIs, including Flow
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlin.Experimental",
// Enable experimental kotlinx serialization APIs
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
)
// Set JVM target to 1.8
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
// gradle/libs.versions.tomlを読み取っている
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
}
}
見慣れた記述がでてきました。なんとなく見えてきたかと思いますが、以下の設定をすると、設定したbuild.gradle.kts
に上記内容がマージされるようです。
結局どうなる
plugins {
id("nowinandroid.android.application")
}
↓ 以下の内容と同義
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
compileSdk = 32
defaultConfig {
targetSdk = 32
minSdk = 21
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = true
}
kotlinOptions {
allWarningsAsErrors = properties["warningsAsErrors"] as? Boolean ?: false
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=kotlin.RequiresOptIn",
// Enable experimental coroutines APIs, including Flow
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlin.Experimental",
// Enable experimental kotlinx serialization APIs
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
)
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
implementation(libs.android.desugarJdkLibs)
}
再度、app/build.gradle.kts
を見ると、必要な記述が足りないのに気づくと思います。このように動作することでビルドの設定を構築しているようです。
感想
マルチモジュールの構成は主流になってきてると思いますし、各種設定やバージョンなどを合わせる方法は試行錯誤してましたので、このような書き方ができることを知れて勉強になりました。
ざっくりではありますが、流れが追えてよかったです。
Discussion