ProductFlavors を設定してるライブラリを使用するときは BuildVariant を指定する必要がある


問題解決するまで少しハマったので備忘録として残します。

> http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

# 問題

アプリはライブラリに依存してます。

```groovy:app/build.gradle
apply plugin: 'com.android.application'

android {
    ...
    
    buildTypes {
        debug   {...}
        release {...}
    }
}

dependencies {
    compile project(':library')
}
```

使用するライブラリは ProductFlavors を設定しています。

```groovy:library/build.gradle
apply plugin: 'com.android.library'

android {
    ...

    buildTypes {
        debug   {...}
        release {...}
    }

    productFlavors {
        flavorRed   {...}
        flavorGreen {...}
        flavorBlue  {...}
    }
}
```


この状態ではビルドは通らず、ライブラリを参照できません。

```java
// Cannot resolve symbol Library
import com.sample.library.Library;
```

# 原因

ライブラリの場合、BuildVariant は `release` がデフォルトとなってます。

> 公式では `By default a library only publishes its release variant.` と言ってるけど、ライブラリではなくアプリケーションの場合もそうなのだろうか...？

```java:BaseExtension.java
package com.android.build.gradle

/**
 * Base 'android' extension for all android plugins.
 *
 * <p>This is never used directly. Instead,
 *<ul>
 * <li>Plugin <code>com.android.application</code> uses {@link AppExtension}</li>
 * <li>Plugin <code>com.android.library</code> uses {@link LibraryExtension}</li>
 * </ul>
 */
public abstract class BaseExtension {

    private String defaultPublishConfig = "release"

    ...
}
```

しかし、Flavor を設定している場合は BuildType と ProductFlavor を組み合わせた BuildVariant の名前を指定する必要があり、当然 `release` のままでは参照できません。なので上記の問題に沿うなら `flavorRedRelease` などを指定するべきです。



# 解決方法

## 1. defaultPublishConfig を変更する

ライブラリ側で、デフォルトの BuildVariant を指定します。

```groovy:library/build.gradle
apply plugin: 'com.android.library'

android {
    ...

    defaultPublishConfig "flavorRedRelease"

    buildTypes {
        debug   {...}
        release {...}
    }

    productFlavors {
        flavorRed {}
        flavorGreen {}
        flavorBlue {}
    }
}
```

しかし、この場合では `flavorRedRelease` しか使えず、他の BuildVariant を指定すると怒られます。

```groovy:app/build.gradle
dependencies {
//  compile project(':library') // OK
    compile project(path: ':library', configuration: 'flavorRedDebug') // NG
}
```

イケてないです。

```
Error:Configuration with name 'flavorRedDebug' not found.
```

## 2. publishNonDefault を true にする

ライブラリ側で、すべての BuildVariant を公開する設定を true にします。

```groovy:library/build.gradle
apply plugin: 'com.android.library'

android {
    ...

    publishNonDefault true

    buildTypes {
        debug   {...}
        release {...}
    }

    productFlavors {
        flavorRed {}
        flavorGreen {}
        flavorBlue {}
    }
}
```

`publishNonDefault` はデフォルトでは false となっています。

```java:BaseExtension.java
package com.android.build.gradle

/**
 * Base 'android' extension for all android plugins.
 *
 * <p>This is never used directly. Instead,
 *<ul>
 * <li>Plugin <code>com.android.application</code> uses {@link AppExtension}</li>
 * <li>Plugin <code>com.android.library</code> uses {@link LibraryExtension}</li>
 * </ul>
 */
public abstract class BaseExtension {

    private boolean publishNonDefault = false

    ...
}
```

これによりアプリ側から、ライブラリの全ての BuildVariant を使用することが可能となります。ただし、ライブラリ側で `defaultPublishConfig` を変更していない場合は、アプリ側から BuildVariant を指定しないと怒られます。

```groovy:app/build.gradle
dependencies {
    compile project(':library') // NG
//  compile project(path: ':library', configuration: 'flavorRedDebug')     // OK
//  compile project(path: ':library', configuration: 'flavorRedRelease')   // OK
//  compile project(path: ':library', configuration: 'flavorGreedDebug')   // OK
//  compile project(path: ':library', configuration: 'flavorGreedRelease') // OK
//  compile project(path: ':library', configuration: 'flavorBlueDebug')    // OK
//  compile project(path: ':library', configuration: 'flavorBlueRelease')  // OK
}
```

```java
// Cannot resolve symbol Library
import com.sample.library.Library;
```

---

`defaultPublishConfig` と `publishNonDefault` のどちらも設定しておくのがベストかと思います。

```groovy:library/build.gradle
apply plugin: 'com.android.library'

android {
    ...

    defaultPublishConfig "flavorRedRelease"
    publishNonDefault true

    buildTypes {
        debug   {...}
        release {...}
    }

    productFlavors {
        flavorRed {}
        flavorGreen {}
        flavorBlue {}
    }
}
```

```groovy:app/build.gradle
dependencies {
//  compile project(':library') // OK
    compile project(path: ':library', configuration: 'flavorRedDebug')     // OK
//  compile project(path: ':library', configuration: 'flavorRedRelease')   // OK
//  compile project(path: ':library', configuration: 'flavorGreedDebug')   // OK
//  compile project(path: ':library', configuration: 'flavorGreedRelease') // OK
//  compile project(path: ':library', configuration: 'flavorBlueDebug')    // OK
//  compile project(path: ':library', configuration: 'flavorBlueRelease')  // OK
}
```

---

検証用プロジェクト
https://github.com/ShogoMizumoto/SampleFlavorsLibrary