Gradleで非標準のSourceSetsを使う
GradleのいわゆるConvention(規約)に抵抗して、好みのプロジェクト構成にしたい。ここでの目標としては、複数の異なるSourceSetsを作り、別々にコンパイルすることである。正直なところ基本がわからないので(いくらマニュアル等を読んでみてもわからない)、ここでは一歩一歩試していく。
標準的な構成
以下が標準的なファイル構成だという(Eclipseを使っているので余計なファイルもある)。
コンパイルするためのbuild.gradleとしては、一行だ。
apply plugin: 'java'
コンパイルのみをしたいので、タスクとしては、「classes」で事足りる。
以下の結果が作成される。
Eclipseの標準配置に合わせる
これをEclipseのJavaプロジェクトの標準配置に合わせたい。この場合は以下に変更する。
※Eclipseのクラス出力先(bin)にgradleの出力を上書きする人はいないだろうが、一応やってみる。
apply plugin: 'java'
sourceSets {
main {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
Javaとリソースで書き方が違うのかわからないが、とりあえずこれで何とかなる。
※ただし、一時ファイル出力用にbuildというディレクトリは使われてしまうようだ。
別のSourceSetにする
mainのソースセットであればcompileJavaやらclassesやらというタスクが使えるが、名前を変えるとそうはいかなくなる。それぞれcompileFoobarJava、foobarClassesという名前になる。もう少し名前を統一的にできなかったものだろうか?
apply plugin: 'java'
sourceSets {
foobar {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
ライブラリ依存を追加してみる
適当に小さめライブラリを依存指定し、それをJavaソースで使う。
apply plugin: 'java'
sourceSets {
foobar {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'javax.inject', name: 'javax.inject', version: '1'
}
import javax.inject.*;
public class Sample {
@Inject
public Sample() {
}
}
見つけ出せないようだ。
Root project 'sample' executing foobarClasses
:compileFoobarJavaC:\devel\workspace\sample\src\Sample.java:1: error: package javax.inject does not exist
import javax.inject.*;
^
C:\devel\workspace\sample\src\Sample.java:5: error: cannot find symbol
@Inject
^
symbol: class Inject
location: class Sample
foobarのコンフィギュレーションをcompileから継承させる
以下のようにすれば良いようだ。つまり、compileというコンフィギュレーションは、あくまでもmainというソースセットのものであって、他のソースセットには適用されないため、foobar用のcompileコンフィギュレーションをそこから派生させなければならない。
apply plugin: 'java'
sourceSets {
foobar {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
configurations {
foobarCompile.extendsFrom compile
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'javax.inject', name: 'javax.inject', version: '1'
}
foobar専用のコンフィギュレーションに依存ライブラリを記述する
そもそも、このライブラリをfoobarにしか使わないものとすればどう書けば良いのか?
依存ライブラリをfoobarCompileコンフィギュレーションに書けばよい。configurations定義は不要になる。
apply plugin: 'java'
apply plugin: 'eclipse'
sourceSets {
foobar {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
repositories {
mavenCentral()
}
dependencies {
// ここを変更
foobarCompile group: 'javax.inject', name: 'javax.inject', version: '1'
}
つまり、本当にfoobarだけにしか使わないライブラリであれば、foobarCompileコンフィギュレーションに依存を書けばよいし、他との共通ライブラリであれば、compileを継承すればよい。
eclipseプラグインはどう対応しているのか?
当方では常にEclipseを使用しているので、ソースセットやコンフィギュレーションが標準で無い場合にどう対応しているのか気になる。
以下のようにeclipseプラグインを追加し、「cleanEclipse eclipse」を実行する。
apply plugin: 'java'
apply plugin: 'eclipse' // 追加
sourceSets {
foobar {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
repositories {
mavenCentral()
}
dependencies {
foobarCompile group: 'javax.inject', name: 'javax.inject', version: '1'
}
もともと、このプラグインには問題がある。ソースや出力先が以下のように設定されてしまうのである。
この対策については、既にGradleのEclipseプラグインの処理結果を変更に記述した。
もう一つの問題は、依存ライブラリが入って来ないことだ。どうもcompileやtestCompileぐらいしか入れてくれないらしい(他のコンフィギュレーションは試したことがない)。
以下のように、コンフィギュレーションを追加してやればよい。
apply plugin: 'java'
apply plugin: 'eclipse'
sourceSets {
foobar {
java {
srcDir 'src'
}
resources {
srcDir 'src'
}
java.outputDir = file('bin')
output.resourcesDir = file('bin')
}
}
repositories {
mavenCentral()
}
dependencies {
foobarCompile group: 'javax.inject', name: 'javax.inject', version: '1'
}
/* これを追加 */
eclipse {
classpath {
plusConfigurations += [configurations.foobarCompile]
}
}
この件の詳細説明はEclipseClasspathにある。
ディスカッション
コメント一覧
まだ、コメントがありません