diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt
index aa4b89faf40..b4ac8578c64 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt
@@ -335,7 +335,14 @@ fun getSomething() = 10
val options = defaultBuildOptions().copy(incremental = false)
project.build("assemble", options = options) {
- assertSuccessful()
+ if (isLegacyAndroidGradleVersion(androidGradlePluginVersion)) {
+ // Library dependencies are not supported in older versions of Android Gradle plugin (< 3.0)
+ assertFailed()
+ assertContains("Unresolved reference: layout_in_library")
+ assertContains("Unresolved reference: text_view")
+ } else {
+ assertSuccessful()
+ }
}
}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/build.gradle
index c80ff935863..7092441fe4d 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/build.gradle
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/build.gradle
@@ -41,4 +41,5 @@ androidExtensions {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ compile project(":library")
}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/src/main/java/MainActivity.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/src/main/java/MainActivity.kt
index aab20643e48..9ccfe49f352 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/src/main/java/MainActivity.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/app/src/main/java/MainActivity.kt
@@ -3,11 +3,13 @@ package org.example.manyvariants
import android.app.Activity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
+import kotlinx.android.synthetic.main.layout_in_library.text_view
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewMain
+ text_view
}
}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/build.gradle
new file mode 100755
index 00000000000..4fb0d31e713
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/build.gradle
@@ -0,0 +1,24 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 23
+ buildToolsVersion "25.0.2"
+
+ defaultConfig {
+ minSdkVersion 15
+ targetSdkVersion 23
+ versionCode 1
+ versionName "1.0"
+
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/AndroidManifest.xml
new file mode 100755
index 00000000000..78138528809
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/res/layout/layout_in_library.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/res/layout/layout_in_library.xml
new file mode 100755
index 00000000000..1e6ceceb4b7
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/res/layout/layout_in_library.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/res/values/strings.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/res/values/strings.xml
new file mode 100755
index 00000000000..6d5185635a6
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/library/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Library
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/settings.gradle
index e7b4def49cb..b0c8eaa09e0 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/settings.gradle
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/AndroidExtensionsManyVariants/settings.gradle
@@ -1 +1 @@
-include ':app'
+include ':app', ':library'
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt
index baacabf9686..687c16971b6 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt
@@ -28,7 +28,6 @@ import org.gradle.api.UnknownDomainObjectException
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.*
-import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.w3c.dom.Document
import java.io.File
@@ -160,74 +159,95 @@ class AndroidSubplugin : KotlinGradleSubplugin {
val pluginOptions = arrayListOf()
pluginOptions += SubpluginOption("experimental", "true")
- pluginOptions += SubpluginOption("defaultCacheImplementation",
- androidExtensionsExtension.defaultCacheImplementation.optionName)
+ pluginOptions += SubpluginOption("defaultCacheImplementation", androidExtensionsExtension.defaultCacheImplementation.optionName)
val mainSourceSet = androidExtension.sourceSets.getByName("main")
pluginOptions += SubpluginOption("package", getApplicationPackage(project, mainSourceSet))
+ val enabledVariants = getVariantComponentNames(variantData)
+ val allResDirectories = mutableMapOf>()
+
+ androidProjectHandler.forEachVariant(project) { variant ->
+ val variantName = androidProjectHandler.getVariantName(variant)
+ if (androidProjectHandler.getTestedVariantData(variant) != null) {
+ return@forEachVariant
+ }
+
+ allResDirectories[variantName] = androidProjectHandler.getResDirectories(variant)
+ }
+
fun addVariant(name: String, resDirectories: List) {
val optionValue = buildString {
- append(name)
- append(';')
+ append(name).append(';')
resDirectories.joinTo(this, separator = ";") { it.canonicalPath }
}
- pluginOptions += CompositeSubpluginOption("variant", optionValue, listOf(
+
+ pluginOptions += CompositeSubpluginOption(
+ "variant", optionValue, listOf(
SubpluginOption("variantName", name),
// use INTERNAL option kind since the resources are tracked as sources (see below)
- FilesSubpluginOption("resDirs", resDirectories)))
+ FilesSubpluginOption("resDirs", resDirectories)
+ )
+ )
kotlinCompile.source(project.files(getLayoutDirectories(resDirectories)))
}
- fun addSourceSetAsVariant(name: String) {
- val sourceSet = androidExtension.sourceSets.findByName(name) ?: return
- val srcDirs = sourceSet.res.srcDirs.toList()
- if (srcDirs.isNotEmpty()) {
- addVariant(sourceSet.name, srcDirs)
- }
- }
+ val actualResDirectories = allResDirectories.filterKeys { it in enabledVariants }
+ val localProjectResDirs = actualResDirectories.values
+ .flatMap { it }
+ .filter { it.isProjectLibraryResDirectory() || it.isPackageResDirectory() }
- val resDirectoriesForAllVariants = mutableListOf>()
+ val commonResDirectories = getCommonResDirectories(allResDirectories.values) + localProjectResDirs
+ addVariant("main", commonResDirectories.distinct().sorted())
- androidProjectHandler.forEachVariant(project) { variant ->
- if (androidProjectHandler.getTestedVariantData(variant) != null) return@forEachVariant
- resDirectoriesForAllVariants += androidProjectHandler.getResDirectories(variant)
- }
+ for (sourceSetName in enabledVariants) {
+ val srcDirs = androidExtension.sourceSets.findByName(sourceSetName)
+ ?.res?.srcDirs?.toList()?.takeIf { it.isNotEmpty() } ?: continue
- val commonResDirectories = getCommonResDirectories(resDirectoriesForAllVariants)
-
- addVariant("main", commonResDirectories.toList())
-
- getVariantComponentNames(variantData)?.let { (variantName, flavorName, buildTypeName) ->
- addSourceSetAsVariant(buildTypeName)
-
- if (flavorName.isNotEmpty()) {
- addSourceSetAsVariant(flavorName)
- }
-
- if (buildTypeName != variantName && buildTypeName != flavorName) {
- addSourceSetAsVariant(variantName)
- }
+ addVariant(sourceSetName, (srcDirs - commonResDirectories).sorted())
}
return wrapPluginOptions(pluginOptions, "configuration")
}
- // Android25ProjectHandler.KaptVariant actually contains BaseVariant, not BaseVariantData
- private fun getVariantComponentNames(flavorData: Any?): VariantComponentNames? = when(flavorData) {
- is KaptVariantData<*> -> getVariantComponentNames(flavorData.variantData)
- is TestVariantData -> getVariantComponentNames(flavorData.testedVariantData)
- is TestVariant -> getVariantComponentNames(flavorData.testedVariant)
- is BaseVariant -> VariantComponentNames(flavorData.name, flavorData.flavorName, flavorData.buildType.name)
- is BaseVariantData<*> -> VariantComponentNames(flavorData.name, flavorData.variantConfiguration.flavorName,
- flavorData.variantConfiguration.buildType.name)
- else -> null
+ private fun File.isPackageResDirectory(): Boolean {
+ val packagedResDir = parentFile ?: return false
+ val intermediatesDir = packagedResDir.parentFile ?: return false
+ val buildDir = intermediatesDir.parentFile ?: return false
+
+ return packagedResDir.name == "packaged_res" && intermediatesDir.name == "intermediates" && buildDir.name == "build"
}
- private data class VariantComponentNames(val variantName: String, val flavorName: String, val buildTypeName: String)
+ private fun File.isProjectLibraryResDirectory(): Boolean {
+ if (name != "res") {
+ return false
+ }
- private fun getCommonResDirectories(resDirectories: List>): Set {
+ val bundlesDir = parentFile?.parentFile ?: return false
+ val intermediatesDir = bundlesDir.parentFile ?: return false
+ val buildDir = intermediatesDir.parentFile ?: return false
+
+ return bundlesDir.name == "bundles" && intermediatesDir.name == "intermediates" && buildDir.name == "build"
+ }
+
+ // Android25ProjectHandler.KaptVariant actually contains BaseVariant, not BaseVariantData
+ private fun getVariantComponentNames(variantData: Any?): List = when(variantData) {
+ is KaptVariantData<*> -> getVariantComponentNames(variantData.variantData)
+ is TestVariantData -> getVariantComponentNames(variantData.testedVariantData)
+ is TestVariant -> getVariantComponentNames(variantData.testedVariant)
+ is BaseVariant -> listOfNotNull(variantData.name, variantData.flavorName, variantData.buildType.name).distinct()
+ is BaseVariantData<*> -> {
+ listOfNotNull(
+ variantData.name,
+ variantData.variantConfiguration.flavorName,
+ variantData.variantConfiguration.buildType.name
+ ).distinct()
+ }
+ else -> emptyList()
+ }
+
+ private fun getCommonResDirectories(resDirectories: Iterable>): Set {
var common = resDirectories.firstOrNull()?.toSet() ?: return emptySet()
for (resDirs in resDirectories.drop(1)) {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt
index 4949db58e64..6e073e686cd 100755
--- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt
@@ -473,12 +473,12 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationT
protected val logger = Logging.getLogger(this.javaClass)
abstract fun forEachVariant(project: Project, action: (V) -> Unit): Unit
+ abstract fun getVariantName(variant: V): String
abstract fun getTestedVariantData(variantData: V): V?
abstract fun getResDirectories(variantData: V): List
protected abstract fun getSourceProviders(variantData: V): Iterable
protected abstract fun getAllJavaSources(variantData: V): Iterable
- protected abstract fun getVariantName(variant: V): String
protected abstract fun getJavaTask(variantData: V): AbstractCompile?
protected abstract fun addJavaSourceDirectoryToVariantModel(variantData: V, javaSourceDirectory: File): Unit