1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

buildSrcディレクトリ で gradleタスクを作成する際にKotlinを使用するにはkotlin gradle pluginの適用が必要

Last updated at Posted at 2022-07-24

サマリー

buildSrcディレクトリを用いてgradleタスクを作成する際にKotlinを使用するには、kotlin gradle pluginの適用が必要でした。
具体的には、buildSrc直下に以下のようなbuild.gradleを追加する必要があります。

buildSrc/build.gradle
// デフォルトで適用される分
// http://gradle.monochromeroad.com/docs/userguide/organizing_build_logic.html
apply plugin: 'groovy'
dependencies {
    implementation gradleApi()
    implementation localGroovy()
}


// 以下カスタム
apply plugin: 'kotlin' // これがないと、buildSrc/arc/main以下にKotlinファイルを置いても実行できなくなる(Ctrl+Bでのジャンプでは認識されるけど)
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        def kotlin_version = '1.6.10' // 多分、アプリ全体とバージョンを合わせないとだめ
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // apply plugin: 'kotlin' に必要

    }
}

repositories {
    mavenCentral()
}

詳細

背景

projectRoot
|
|-buildSrc
|    |-src
|       |-main
|           |-java
|               |-GreetingTaskKotlin.kt
|               |-GreetingTaskJava.java
|
|-app
|  |-src
|  |  |-main
|  |       |
|  |    (以下略)
|  |
|  |-build.gradle
|
|-build.gradle

というディレクトリ構成で、(projectRootの)build.gradle から使用するためのカスタムGradleタスクを作成しました。  
そうしたところ、GreetingTaskJava.javaの方に定義したタスクはbuild.gradle から使用できるけどGreetingTaskKotlin.ktに定義したものは使用できませんでした。

ネット上に情報が少なく、またAndroidStudio上でのCtrl+Bでの定義ジャンプはGreetingTaskKotlin.ktに対しても正常に動いていたのもあり、何が悪いのかわからず解決に時間がかかってしまったので備忘録でした。

環境

gradle : v7.0.2
android gradle plugin (GAP) : v7.0.4
kotlin : v1.6.10

そもそもbuildSrc を用いてGradleタスクを作成するとは

Gradleのユーザーガイドの第58章 カスタムタスクの作成 の「58.1. タスククラスのパッケージング」で紹介されているものの2個めの「buildSrcプロジェクト」のことです。

この方法でタスクを作成した場合、buildSrcに対するbuild.gadleは設定していなくてもシステムが自動的に以下のスクリプトを適用します。
(ユーザーガイド : http://gradle.monochromeroad.com/docs/userguide/organizing_build_logic.html より)

apply plugin: 'groovy'
dependencies {
    compile gradleApi()
    compile localGroovy()
}

ユーザーガイドは少し古いので、compileを使用しています。ですがこちらはGAP v7.0.4ではサポートが終わっているので、GAP v7.0.4にあわせて書き直した場合以下です。

apply plugin: 'groovy'
dependencies {
    implementation gradleApi()
    implementation localGroovy()
}

※正確には元の動きを尊重するにはcompileapiに置き換えるべきですが ここでは依存関係をほかのモジュールに推移的にエクスポートする必要はないのでimplementation にしてしまっています。

さて、buildSrc以下に置くタスク定義ファイルにjavaを使用した場合はシステムが自動的に適用してくれるbuild.gradleを用いたビルドだけでプロジェクトルートのbuild.gradleやアプリケーションモジュールのbuild.gradleからタスクとして使用できるようになります。したがってbuildSrc以下に独自にbuild.gradleを置く必要は特にありません。

ただ、Kotlinを使用したファイルで定義してタスクの場合はそれでは認識されません。
(なぜかAndroid Studio上での定義ジャンプや入力補完は効きますが...)

apply plugin: 'kotlin'の適用もしてやらないといけないようです。したがって、#サマリーに記載したbuild.gradlebuildSrc直下においてやります。

おまけ そのほかのファイル

タスクを定義しているGreetingTaskJava.javaGreetingTaskKotlin.kt

GreetingTaskJava.java
package com.kkkkan.buildscript;

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;


public class GreetingTaskJava extends DefaultTask {
  @TaskAction
  void greet(){
    System.out.println("Hello from Java.");
  }
}
GreetingTaskKotlin.kt
package com.kkkkan.buildscript

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

abstract class GreetingTaskKotlin : DefaultTask() {
    
    @TaskAction
    fun greet() {
        println("Hello from Kotlin.")
    }
}

GreetingTaskJava.javaGreetingTaskKotlin.kt で定義したタスクを使用する側(プロジェクトのルートやアプリケーションモジュールのbuild.gradle)

プロジェクトのルートのbuild.gradleの場合、

projectRooot/build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

// -------元々あったもの ここから-------------
buildscript {
    ext.kotlin_version = '1.6.10' // composeライブラリv1.1.1はkotlin v1.6.10に依存しているのでこれ以上あげられない
    ext.compose_version = '1.1.1'
    repositories {
        google()
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.4'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        (以下略)

    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

// -------元々あったもの ここまで-------------







// ------追加ここから------------------
import com.kkkkan.buildscript.GreetingTaskJava
import com.kkkkan.buildscript.GreetingTaskKotlin

task greetJava(type:GreetingTaskJava)
task greetKotlin(type: GreetingTaskKotlin)
// ------追加ここまで------------------

と最後の4行を付け足して、
gradlew greetJava(Windows)/./gradlew greetJava(Mac) でGreetingTaskJava#greet
gradlew greetKotlin(Windows)/./gradlew greetKotlin(Mac) でGreetingTaskKotlin#greet
が実行できるようになります。

なお、しつこいですがbuildSrc/build.gradleを作成しなくてもgradlew greetJava(Windows)/./gradlew greetJava(Mac) は実行できます。
(import com.kkkkan.buildscript.GreetingTaskKotlintask greetKotlin(type: GreetingTaskKotlin))をコメントアウト)しておけば)

アプリケーションモジュールの時もapp/build.gradleに最後の4行を同様に追加して、gradlew greetKotlin(Windows)もしくはgradlew app:greetKotlin(Windows)などで同様に実行できます。(app/build.gradleに設定した場合でも、gradlew app:greetKotlinではなくappを省略してgradlew greetKotlinだけでも大丈夫なようです。知らなかった....)

感想

  • Kotlinを使うならkotlinプラグインを入れないとだめなんて、言われてみれば当たり前なんだけど、なまじ定義ジャンプや入力補完が効くので気づくのに時間がかかってしまった。
  • Gradl関係を検索するとKotlin DSLを使用したもの、が多くて、groovyのまま通しつづけるのはそろそろ年貢の納め時なのかな...という気分になりました。今回の本題とは全然関係ないけども。

参考にしたもの

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?