nashcft's blog

時々何か書く。

最近触った Gradle 関連の機能

備忘録のようなもの。

Gradle

Version catalogs

docs.gradle.org

Project root の build.gradleext に生やしたり buildSrc や composite build 用 module 内に object declaration で定義されたりするような慣習のあった依存ライブラリの定義用の機能。 7.0 で experimental feature として導入され、7.4 で stable になった。

定義の方は settings.gradle(.kts) に書く方法と .toml ファイルに書く方法、複数の catalog を作ったり toml の方は読み込むファイルの指定をしたり定義した library 依存をまとめて指定できる bundle という設定があったりと色々あるが、全部 docs の内容の写しになってしまうし、それをつらつらと書くとしても量が多くて面倒なので docs を読んでほしい。自分の躓き体験としては toml ファイルで定義するときはファイルの置き場がデフォルトでは gradle/ なのだが、それに気づかず project root に置いてて生成されなくて悩んでたというのがあった。

これを設定すると ProjectgetExtensions() (もしくは extensions) で取得できる ExtensionContainer に定義した名前で LibrariesFor<定義した名前> が登録されて、そこから catalogs に登録した情報にアクセスできるようになる。それぞれの値に対する alias name には -, _, あと . を使うことができるが、これらは全て catalog の階層の区切りとして扱われる。

例えば以下のように定義した場合:

[libraries]
kotlin-stdlib = { ... }
kotlin-stdlib-jdk8 { ... }

kotlinx-coroutines-core = { ... }
kotlinx-coroutines-android = { ... }
kotlinx-serialization-json = { ... }
kotlinx-serialization-protobuf = { ... }

呼び出し側は以下のようになる:

dependencies {
  implementation(libs.kotlin.stdlib)
  implementation(libs.kotlin.stdlib.jdk8)

  implementation(libs.kotlinx.coroutines.core)
  implementation(libs.kotlinx.coroutines.android)
  implementation(libs.kotlinx.serialization.json)
  implementation(libs.kotlinx.serialization.protobuf)
}

ところで呼び出し側は補完が効くようになるので便利だが、呼び出し箇所から定義にジャンプできない (生成された LibrariesFor<定義した名前> 内の get method に飛んでしまう) ので、 object declaration で定義してた状態から移行するとその点に関しては不便を感じる。

ある程度決まった文法をしているけど、要は適当な String value を名前をつけて登録できる機能みたいな見方ができるので使用には多少の自制心を求められそうな気もする (version はその気配を特に感じる)。

Type-safe project accessors

docs.gradle.org

Project 内の module への依存 (こういうのを "project dependency" と言うそうだ) を記述するときは project(":module:path") みたいな書き方をしていたが、 path が String のリテラルってまあ面倒だよねということで 7.0 から experimental feature として導入された。

Version catalogs と違ってこっちは 7.4 の時点でまだ experimental から抜けてないので使えるようにするには settings.gradle(.kts) に以下の記述を追加する必要がある:

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

これが有効になると、 version catalogs と同じような感じで extensions から "projects"RootProjectAccessor が取れるようになり、依存の記述を以下のようにすることができる:

dependencies {
  // これが
  implementation(project(":module:path"))
  // こう
  implementation(projects.module.path)
}

区切りの法則が version catalogs と異なり、 path の : 毎に . 区切りとなって、 名前の -_ は camelCase に変換される:

// これが
project(":path:to:awesome-module")
// こんな感じ
projects.path.to.awesomeModule

仕組みは概ね version catalogs と同様な感じ。なので jump しても生成された class の method に飛ばされるだけだが、こちらは特に飛ばされてほしい先が無いので version catalogs ほど不便に感じないかも知れない。

これと version catalogs 関連のコードを読みたかったら org.gradle.api.internal.catalog package まわりから始めることになりそう。

Precompiled script plugins

docs.gradle.org

buildSrc の src 内に置いた .gradle(.kts) の gradle script が各 module の build.gradle で plugin として参照できるよって話。上記の docs と以下の記事を読めば何となく使えるようになる。

mike-neck.hatenadiary.com

AGP

Publishing DSL

developer.android.com

androidstudio.googleblog.com

AGP 7.1.0 から導入された。 Maven publishing のために生成するsoftware component を自動生成ではなく自分で指定する方式に変えるようで、そのための DSL だそうだ。 AGP 7.1.0 の時点でこの設定を行わずに maven publishing plugin を使用している場合以下の warning が表示される:

WARNING:Software Components will not be created automatically for Maven publishing from Android Gradle Plugin 8.0. To opt-in to the future behavior, set the Gradle property android.disableAutomaticComponentCreation=true in the gradle.properties file or use the new publishing DSL.

使い方は簡単で、 android {} の中で publishing {} を呼び出して、その中で publish したい build variant を指定すればOK。

android {
  // ...
  publishing {
    singleVariant("release") {
      // Sources jar を生成させるための option
      withSourcesJar()
      // JavaDoc jar を生成させるための option
      withJavadocJar()
    }
  }
}

詳しいことは JavaDoc 読むのが良い。

JavaDoc がやけに充実しているのは Android Developers の maven publishing plugin のページの内容が更新されるまでの繋ぎとしてここに書いているからとのこと。

https://cs.android.com/android-studio/platform/tools/base/+/2e1ff8e3b05a4fcaad12066c6f38633b6875a2ae

As we have to wait the feature goes into beta to update the DAC page https://developer.android.com/studio/build/maven-publish-plugin, it would be nice to have more java doc including some code samples to introduce this new feature to users. And we could have a brief note in our release notes and point users to the java doc. Once we are able to update the DAC page, we could simplify the java doc.

developer.android.com