build.gradle.kts で gradle.properties (project properties) を参照する
はじめに
Groovy と kts で project property の参照方法が違っていたのでまとめました。
gradle.properties (project properties)
- gradle.properties で定義されたプロパティは project properties と呼ばれ、gradle のビルドスクリプト内で参照できる
- project properties は(gradle.properties 含め)以下の入力元から値が読み込まれる
gradle.properties
app/gradle.properties
-
$GRADLE_USER_HOME/gradle.properties
- (
$GRADLE_USER_HOME
のデフォルト値は$HOME/.gradle
)
- (
- 環境変数 (例えば
ORG_GRADLE_PROJECT_conf_foo=foo
など) - gradle の
-P
実行オプション
- gradle.properties から値を渡すことで、設定値を一元管理したり、ソースコードと設定値を分離したり、環境ごとに設定値を切り替えたりできる
gradle.properties の例
gradle.properties では以下のような key-value 形式で値を設定する
gradle.properties
conf_foo=_foo_
Groovy での参照方法
build.gradle
// OK パターン
conf_foo # => _foo_
project.conf_foo # => _foo_
project.properties["conf_foo"] # => _foo_
// NG パターン
properties["conf_foo"] # => null (なぜ?)
kts での参照方法
build.gradle.kts
// OK パターン
val conf_foo: String by project # => conf_foo == "_foo_"
project.properties["conf_foo"] # => _foo_
properties["conf_foo"] # => _foo_
// NG パターン
conf_foo # => Unresolved reference
project.conf_foo # => Unresolved reference
書き方の違いについて
Groovy はメタプログラミングができるので conf_foo
あるいは project.conf_foo
を参照したときに project.properties["conf_foo"]
に移譲するような実装になっている。 [1]
一方 Kotlin の val conf_foo: String by project
では provideDelegate operator で PropertyDelegate 委譲オブジェクトを生成している。委譲オブジェクトを使う書き方があるということは Groovy と同じような conf_foo
あるいは project.conf_foo
での参照は kotlin の文法的にできなそうな雰囲気を感じる。
(おまけ) buildConfigField
buildConfigField を defaultConfig や BuildType あるいは BuildFlavor の中に記述し、プロジェクトプロパティを渡すことで BuildConfig.FOO
のような形でアプリケーションコードから値を参照できるようになる。
defaultConfig {
// ...
buildConfigField("String", "FOO", "\"${properties["conf_foo"]}\"")
}
ダブルクォーテーションを(エスケープして)値に含めているのは、そうしないと生成される BuildConfig.java 内で
public static final String FOO = foo;
のように出力されてエラーになるからであり、何か特別なシンタックスというわけではない。
また、上記の書き方では参照する project property が存在しない場合に
public static final String FOO = "null";
となってしまうので注意が必要。
参考
- Project properties | docs.gradle.org
- The Apache Groovy programming language - Runtime and compile-time metaprogramming
- Gradle のヒントとテクニック | Android デベロッパー | Android Developers
- ビルド時にいろんな値を生成する - メモ2ブログ
- In gradle, is there a property access syntax for init scripts? : r/Kotlin
- android - Reference property in Gradle Properties - Stack Overflow
-
metaClass の invokeMethod / methodMissing / propertyMissing あたりを使っているっぽいがちゃんとコードを追ってはいない ↩︎
Discussion