Android import: simplified configuration matching
This commit is contained in:
+15
-40
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.dsl
|
package org.jetbrains.kotlin.gradle.dsl
|
||||||
|
|
||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.BaseExtension
|
||||||
|
import com.android.build.gradle.api.AndroidSourceSet
|
||||||
import com.android.build.gradle.internal.LoggerWrapper
|
import com.android.build.gradle.internal.LoggerWrapper
|
||||||
import com.android.build.gradle.internal.SdkLocationSourceSet
|
import com.android.build.gradle.internal.SdkLocationSourceSet
|
||||||
import com.android.build.gradle.internal.SdkLocator
|
import com.android.build.gradle.internal.SdkLocator
|
||||||
@@ -27,7 +28,6 @@ import org.gradle.internal.component.external.model.DefaultModuleComponentIdenti
|
|||||||
import org.gradle.util.ConfigureUtil
|
import org.gradle.util.ConfigureUtil
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -82,24 +82,27 @@ open class KotlinMultiplatformExtension :
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getAndroidSourceSetDependencies(project: Project): Map<String, List<File>?> {
|
fun getAndroidSourceSetDependencies(project: Project): Map<String, List<File>?> {
|
||||||
val ext = project.extensions.getByName("android") as BaseExtension
|
data class SourceSetConfigs(val implConfig: Configuration, val compileConfig: Configuration)
|
||||||
|
|
||||||
val androidSdkJar = getAndroidSdkJar(project) ?: return emptyMap()
|
val androidSdkJar = getAndroidSdkJar(project) ?: return emptyMap()
|
||||||
|
val sourceSet2Impl = HashMap<String, SourceSetConfigs>()
|
||||||
|
val allImplConfigs = HashSet<Configuration>()
|
||||||
|
|
||||||
val sourceSet2Impl = ext.sourceSets.map {
|
project.forEachVariant { variant ->
|
||||||
lowerCamelCaseName("android", it.name) to project.configurations.getByName(it.implementationConfigurationName)
|
val compileConfig = variant.compileConfiguration
|
||||||
}.toMap()
|
variant.sourceSets.filterIsInstance(AndroidSourceSet::class.java).map {
|
||||||
|
val implConfig = project.configurations.getByName(it.implementationConfigurationName)
|
||||||
val allImplConfigs = sourceSet2Impl.values.toSet()
|
allImplConfigs.add(implConfig)
|
||||||
val impl2CompileClasspath = mapImplementationToCompileClasspathConfiguration(project, allImplConfigs)
|
sourceSet2Impl[lowerCamelCaseName("android", it.name)] = SourceSetConfigs(implConfig, compileConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sourceSet2Impl.mapValues { entry ->
|
return sourceSet2Impl.mapValues { entry ->
|
||||||
val compileClasspathConf = impl2CompileClasspath[entry.value] ?: return@mapValues null
|
val dependencies = findDependencies(allImplConfigs, entry.value.implConfig)
|
||||||
|
|
||||||
val dependencies = findDependencies(allImplConfigs, entry.value)
|
|
||||||
|
|
||||||
val selfResolved = dependencies.filterIsInstance<SelfResolvingDependency>().flatMap { it.resolve() }
|
val selfResolved = dependencies.filterIsInstance<SelfResolvingDependency>().flatMap { it.resolve() }
|
||||||
val resolvedExternal = dependencies.filterIsInstance<DefaultExternalModuleDependency>()
|
val resolvedExternal = dependencies.filterIsInstance<DefaultExternalModuleDependency>()
|
||||||
.flatMap { collectDependencies(it.module, compileClasspathConf) }
|
.flatMap { collectDependencies(it.module, entry.value.compileConfig) }
|
||||||
|
|
||||||
val result = (selfResolved + resolvedExternal + androidSdkJar).toMutableList()
|
val result = (selfResolved + resolvedExternal + androidSdkJar).toMutableList()
|
||||||
|
|
||||||
@@ -162,34 +165,6 @@ open class KotlinMultiplatformExtension :
|
|||||||
result.addAll(configs.flatMap { it.dependencies })
|
result.addAll(configs.flatMap { it.dependencies })
|
||||||
doFindDependencies(implConfigs, configs.flatMap { it.extendsFrom }.filter { it !in implConfigs && visited.add(it) }, result)
|
doFindDependencies(implConfigs, configs.flatMap { it.extendsFrom }.filter { it !in implConfigs && visited.add(it) }, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapImplementationToCompileClasspathConfiguration(
|
|
||||||
project: Project,
|
|
||||||
allImplConfigs: Set<Configuration>
|
|
||||||
): Map<Configuration, Configuration> {
|
|
||||||
val compileClasspathConfigurations = project.configurations.filter { it.name.endsWith("CompileClasspath", true) }
|
|
||||||
return compileClasspathConfigurations.flatMap { ccConf ->
|
|
||||||
findImplementationConfigurations(allImplConfigs, ccConf).map { it to ccConf }
|
|
||||||
}.toMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findImplementationConfigurations(
|
|
||||||
allImplConfigs: Set<Configuration>,
|
|
||||||
compileClasspathConf: Configuration
|
|
||||||
): Set<Configuration> {
|
|
||||||
return HashSet<Configuration>().also { doFindImplementationConfigurations(allImplConfigs, listOf(compileClasspathConf), it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private tailrec fun doFindImplementationConfigurations(
|
|
||||||
allImplConfigs: Set<Configuration>,
|
|
||||||
conf: List<Configuration>,
|
|
||||||
result: MutableSet<Configuration>,
|
|
||||||
visited: MutableSet<Configuration> = HashSet()
|
|
||||||
) {
|
|
||||||
if (conf.isEmpty()) return
|
|
||||||
result.addAll(conf.flatMap { it.extendsFrom.filter { newConf -> allImplConfigs.contains(newConf) } })
|
|
||||||
doFindImplementationConfigurations(allImplConfigs, conf.flatMap { it.extendsFrom }.filter { visited.add(it) }, result)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KotlinTarget.isProducedFromPreset(kotlinTargetPreset: KotlinTargetPreset<*>): Boolean =
|
internal fun KotlinTarget.isProducedFromPreset(kotlinTargetPreset: KotlinTargetPreset<*>): Boolean =
|
||||||
|
|||||||
+22
-6
@@ -1,7 +1,6 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.*
|
||||||
import com.android.build.gradle.BasePlugin
|
|
||||||
import com.android.build.gradle.api.AndroidSourceSet
|
import com.android.build.gradle.api.AndroidSourceSet
|
||||||
import com.android.build.gradle.api.BaseVariant
|
import com.android.build.gradle.api.BaseVariant
|
||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
@@ -707,7 +706,6 @@ class KotlinConfigurationTools internal constructor(
|
|||||||
abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTools: KotlinConfigurationTools) {
|
abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTools: KotlinConfigurationTools) {
|
||||||
protected val logger = Logging.getLogger(this.javaClass)
|
protected val logger = Logging.getLogger(this.javaClass)
|
||||||
|
|
||||||
abstract fun forEachVariant(project: Project, action: (BaseVariant) -> Unit): Unit
|
|
||||||
abstract fun getResDirectories(variantData: BaseVariant): FileCollection
|
abstract fun getResDirectories(variantData: BaseVariant): FileCollection
|
||||||
abstract fun getFlavorNames(variant: BaseVariant): List<String>
|
abstract fun getFlavorNames(variant: BaseVariant): List<String>
|
||||||
abstract fun getBuildTypeName(variant: BaseVariant): String
|
abstract fun getBuildTypeName(variant: BaseVariant): String
|
||||||
@@ -781,7 +779,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool
|
|||||||
androidPluginIds.joinToString("\n\t") { "* $it" })
|
androidPluginIds.joinToString("\n\t") { "* $it" })
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachVariant(project) { variant ->
|
project.forEachVariant { variant ->
|
||||||
val variantName = getVariantName(variant)
|
val variantName = getVariantName(variant)
|
||||||
|
|
||||||
// Create the compilation and configure it first, then add to the compilations container. As this code is executed
|
// Create the compilation and configure it first, then add to the compilations container. As this code is executed
|
||||||
@@ -801,7 +799,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
project.whenEvaluated {
|
project.whenEvaluated {
|
||||||
forEachVariant(project) { variant ->
|
forEachVariant { variant ->
|
||||||
val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant))
|
val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant))
|
||||||
postprocessVariant(variant, compilation, project, ext, plugin)
|
postprocessVariant(variant, compilation, project, ext, plugin)
|
||||||
|
|
||||||
@@ -868,7 +866,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool
|
|||||||
if (kotlinAndroidTarget.disambiguationClassifier != null) {
|
if (kotlinAndroidTarget.disambiguationClassifier != null) {
|
||||||
|
|
||||||
val sourceSetToVariants = mutableMapOf<AndroidSourceSet, MutableList<BaseVariant>>().apply {
|
val sourceSetToVariants = mutableMapOf<AndroidSourceSet, MutableList<BaseVariant>>().apply {
|
||||||
forEachVariant(project) { variant ->
|
project.forEachVariant { variant ->
|
||||||
for (sourceSet in getSourceProviders(variant)) {
|
for (sourceSet in getSourceProviders(variant)) {
|
||||||
val androidSourceSet = sourceSet as? AndroidSourceSet ?: continue
|
val androidSourceSet = sourceSet as? AndroidSourceSet ?: continue
|
||||||
getOrPut(androidSourceSet) { mutableListOf() }.add(variant)
|
getOrPut(androidSourceSet) { mutableListOf() }.add(variant)
|
||||||
@@ -1145,3 +1143,21 @@ internal fun compareVersionNumbers(v1: String?, v2: String?): Int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Project.forEachVariant(action: (BaseVariant) -> Unit) {
|
||||||
|
val androidExtension = this.extensions.getByName("android")
|
||||||
|
when (androidExtension) {
|
||||||
|
is AppExtension -> androidExtension.applicationVariants.all(action)
|
||||||
|
is LibraryExtension -> {
|
||||||
|
androidExtension.libraryVariants.all(action)
|
||||||
|
if (androidExtension is FeatureExtension) {
|
||||||
|
androidExtension.featureVariants.all(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is TestExtension -> androidExtension.applicationVariants.all(action)
|
||||||
|
}
|
||||||
|
if (androidExtension is TestedExtension) {
|
||||||
|
androidExtension.testVariants.all(action)
|
||||||
|
androidExtension.unitTestVariants.all(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+2
-19
@@ -6,7 +6,8 @@
|
|||||||
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
|
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
|
||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import com.android.build.gradle.*
|
import com.android.build.gradle.BaseExtension
|
||||||
|
import com.android.build.gradle.BasePlugin
|
||||||
import com.android.build.gradle.api.*
|
import com.android.build.gradle.api.*
|
||||||
import com.android.build.gradle.tasks.MergeResources
|
import com.android.build.gradle.tasks.MergeResources
|
||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
@@ -29,24 +30,6 @@ class Android25ProjectHandler(
|
|||||||
kotlinConfigurationTools: KotlinConfigurationTools
|
kotlinConfigurationTools: KotlinConfigurationTools
|
||||||
) : AbstractAndroidProjectHandler(kotlinConfigurationTools) {
|
) : AbstractAndroidProjectHandler(kotlinConfigurationTools) {
|
||||||
|
|
||||||
override fun forEachVariant(project: Project, action: (BaseVariant) -> Unit) {
|
|
||||||
val androidExtension = project.extensions.getByName("android")
|
|
||||||
when (androidExtension) {
|
|
||||||
is AppExtension -> androidExtension.applicationVariants.all(action)
|
|
||||||
is LibraryExtension -> {
|
|
||||||
androidExtension.libraryVariants.all(action)
|
|
||||||
if (androidExtension is FeatureExtension) {
|
|
||||||
androidExtension.featureVariants.all(action)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is TestExtension -> androidExtension.applicationVariants.all(action)
|
|
||||||
}
|
|
||||||
if (androidExtension is TestedExtension) {
|
|
||||||
androidExtension.testVariants.all(action)
|
|
||||||
androidExtension.unitTestVariants.all(action)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun wireKotlinTasks(
|
override fun wireKotlinTasks(
|
||||||
project: Project,
|
project: Project,
|
||||||
compilation: KotlinJvmAndroidCompilation,
|
compilation: KotlinJvmAndroidCompilation,
|
||||||
|
|||||||
+2
-2
@@ -64,7 +64,7 @@ open class KotlinAndroidTarget(
|
|||||||
private fun checkPublishLibraryVariantsExist() {
|
private fun checkPublishLibraryVariantsExist() {
|
||||||
fun AbstractAndroidProjectHandler.getLibraryVariantNames() =
|
fun AbstractAndroidProjectHandler.getLibraryVariantNames() =
|
||||||
mutableSetOf<String>().apply {
|
mutableSetOf<String>().apply {
|
||||||
forEachVariant(project) {
|
project.forEachVariant {
|
||||||
if (getLibraryOutputTask(it) != null)
|
if (getLibraryOutputTask(it) != null)
|
||||||
add(getVariantName(it))
|
add(getVariantName(it))
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ open class KotlinAndroidTarget(
|
|||||||
|
|
||||||
private fun AbstractAndroidProjectHandler.doCreateComponents(): Set<KotlinTargetComponent> {
|
private fun AbstractAndroidProjectHandler.doCreateComponents(): Set<KotlinTargetComponent> {
|
||||||
val publishableVariants = mutableListOf<BaseVariant>()
|
val publishableVariants = mutableListOf<BaseVariant>()
|
||||||
.apply { forEachVariant(project) { add(it) } }
|
.apply { project.forEachVariant { add(it) } }
|
||||||
.toList() // Defensive copy against unlikely modification by the lambda that captures the list above in forEachVariant { }
|
.toList() // Defensive copy against unlikely modification by the lambda that captures the list above in forEachVariant { }
|
||||||
.filter { getLibraryOutputTask(it) != null && publishLibraryVariants?.contains(getVariantName(it)) ?: true }
|
.filter { getLibraryOutputTask(it) != null && publishLibraryVariants?.contains(getVariantName(it)) ?: true }
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -208,7 +208,7 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
|
|
||||||
val resDirectoriesForAllVariants = mutableListOf<FileCollection>()
|
val resDirectoriesForAllVariants = mutableListOf<FileCollection>()
|
||||||
|
|
||||||
androidProjectHandler.forEachVariant(project) { variant ->
|
project.forEachVariant { variant ->
|
||||||
if (getTestedVariantData(variant) != null) return@forEachVariant
|
if (getTestedVariantData(variant) != null) return@forEachVariant
|
||||||
resDirectoriesForAllVariants += androidProjectHandler.getResDirectories(variant)
|
resDirectoriesForAllVariants += androidProjectHandler.getResDirectories(variant)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user