Infinito Nirone 7

白羽の矢を刺すスタイル

Android Plugin for Gradle 3.1.0 で The SourceSet 'xxx' is not recognized by Android Gradle Plugin

Android Studio が 3.1.0 になったのに合わせて Android Plugin for Gradle も 3.1.0 が出ました。

Android Plugin for Gradle Release Notes | Android Studio

リリースノートには記述がありませんが、alpha のころから存在する問題として、3.1.0 にあげると"The SourceSet 'xxx' is not recognized by Android Gradle Plugin"というエラーでビルドが失敗する場合があるようです。 たまたま自分もこの問題にぶちあたったので、何がダメでどうするとよいかをメモしておきます。

次のような build.gradle がある前提です。 minSdktypeのふたつの flavorDimensions があり、variantFilter で api19FlavorA だけを無視する設定です。

android {
  flavorDimensions 'minSdk', 'type'

  productFlavors {
    api19 {
      dimension 'minSdk'
      minSdkVersion 19
    }
    api21 {
      dimension 'minSdk'
      minSdkVersion 21
    }
    flavorA {
      dimension 'type'
    }
    flavorB {
      dimension 'type'
    }
  }

  variantFilter { variant ->
    def names = variant.flavors*.name
    if (names.contains('api19') && names.contains('flavorA') {
      setIgnore(true)
    }
  }
}

このとき api19FlavorA の SourceSet を設定すると、タイトルにあるようなThe SourceSet 'xxx' is not recognized by Android Gradle Pluginというエラーが発生します。 Android Plugin for Gradle 3.0.x まではとくにエラーになるものではありませんでしたが、3.1.0 からはダメなようです。

上記のビルドスクリプトでは variantFilter で variant を setIgnore(true) する条件が ProductFlavor の名前だけなので、不注意でないかぎり無視した ProductFlavor の SourceSet を設定することはないと思いますが、無視する条件が環境によって変わる場合は、それにあわせて SourceSet の設定を変えてやる必要があります。

def disable_condition = // Condition to disable api19Flavor variant

android {
  // ...

  variantFilter { variant ->
    def names = variant.flavors*.name
    if (disable_condition && names.contains('api19') && names.contains('flavorA') {
      setIgnore(true)
    }
  }

  sourceSets {
    if (!disable_condition) {
      api19FlavorA {
        // api19FlavorA SourceSet configuration under a specific condition
      }
    }
    api19FlavorB {
      // always configure SourceSet for api19FlavorB
    }
    // ...
  }
}