build.gradleの共通設定

2018年12月3日

複数のプロジェクトには、それぞれ別のbuild.gradleが必要になるが、大きく共通化したい処理も当然ながら存在する。これらを、プロジェクトごとのbuild.gradleとは別の共通ファイルに追い出し、各build.gradleはそれを読み込むようにしたい。

gradle.properties

まず、ユーザホームディレクトリ/.gradleの中のgradle.propertiesであるが(Windowsの場合はc:\users\ユーザ名\.gradle\gradle.properties)、これはいわゆるproperties形式であって、プロパティしか記述することはできない。

しかし、これはすべてのbuild.gradleがデフォルトで読み込んでいるため、ここに別の共通ファイルの場所を記述することにする。

gradle.propertiesは、例えば以下のようになる(注意:ここではバックスラッシュは使えない)。

org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Duser.language=en
org.gradle.java.home=C:/Program Files/Java/jdk1.8.0_112
COMMON_GRADLE=C:/Foo/Bar/common.gradle

初期化スクリプト

なお、ここで実現する仕組みとは別に初期化スクリプトというものがある。これで用が足せるのであれば、こちらを使った方がよいだろう。

しかし、ここでは「ユーザホーム」以外の場所に共通処理を置きたかったので、別の方式を採用している。

apply fromでの取り込み

各build.gradleでは、このCOMMON_GRADLEをapply fromを使って読み込む。

apply from: COMMON_GRADLE
apply plugin: 'java'  
apply plugin: 'eclipse'

....

あとは、最初に指定したように、「C:/Foo/Bar/common.gradle」というファイルに好きな設定を書けばよい。

が、そう簡単にはいかない。

ものの本やウェブの書き込みには「build.gradleに取り込まれるだけなので、build.gradleと同じ記述ができる」とするものもあるが、しかし、どうやっても同じ記述はできない。クラスも関数も定義できない。どういう仕組みになっているのか(gradleではいつものことなのだが)全く理解できない。

Q&A掲示板のようなところで、gradle開発者と思しき人物が答えている場合もあるのだが、彼は「ここを見ろ」といったようなまとまった文書を示しもしていないので、そういったものも無いのかもしれない。

プロパティの定義はできるようである。あるいはタスクの定義はできる。common.gradleは例えば以下のようになる。

ext { // これが必要

// 何らかの変数の定義
CENTRAL_REPOSITORY='http://10.8.92.1:8082/artifactory/libs-release'

// 変数にクロージャを設定
removeOutputFoldersForSourceFolders = { cp->
  cp.entries.findAll{ it.kind == 'src' }.each{
    it.output = null
  }
}

} // 閉じる

// 全コンフィギュレーションとその依存関係を表示
task showConfigurations()  { doLast {
  configurations.getAll().each{ 
    println it.getName()
    it.getExtendsFrom().forEach {
      println "  " + it.getName()
    }
  }
}}

// これは呼び出せない
def getInt() {
  123
}

あまたのウェブの例を参考にやってみても、これ以外の方法ではマトモに動かなかった。結局はextの中でプロパティを定義する以外のことはできないようだ。

ただし、上記のようにtaskは自由に定義できる。

defはローカル

Groovyの仕様上、defは「ローカル」なのだという。しかし、このローカルの意味が明確にわからないのだが、おそらくはファイルが分割されていると参照ができないものと思われる。

ただし、いったんextプロパティに入れれば参照は可能になる。

common.gradle

def add(a) {
 a + 123
}
ext.ADD = { a -> 
 add(a)
}

build.gradle

task showTest() << {
  println GETINT(222)
}

まとめ

以上で、少なくともすべてのbuild.gradleにおいて、共通の変数(及びそこに格納されたクロージャ)を定義することはできる。

より良い方法もあるかもしれないが、少なくとも私にとっては十分であるので、とりあえずこれで行く。

これをEclipse-IDE環境で利用する便利な方法については、GradleのEclipseプラグインの処理結果を変更を参照のこと。