Use same models in MPP and CIDR

This commit is contained in:
Kirill Shmakov
2019-07-15 14:46:19 +03:00
parent 2cc6bf31e0
commit 407e5a5270
10 changed files with 170 additions and 22 deletions
+15 -1
View File
@@ -23,6 +23,17 @@ if (flags.includeCidrPlugins) {
logger.info("NOT including CIDR plugins in buildSrc/settings.gradle")
}
if (flags.hasKotlinUltimate) {
logger.info("Including extension for IJ Ultimate in buildSrc/settings.gradle")
include ":prepare-deps:lldb-frontend"
include ":prepare-deps:native-debug-plugin"
project(":prepare-deps:lldb-frontend").projectDir = file("${flags.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-frontend")
project(":prepare-deps:native-debug-plugin").projectDir = file("${flags.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/native-debug-plugin")
} else {
logger.info("Not including extension for IJ Ultimate in buildSrc/settings.gradle")
}
class LocalBuildPropertiesProvider {
private Settings settings
private Properties localProperties = new Properties()
@@ -57,8 +68,11 @@ class LocalBuildProperties {
boolean includeCidrPlugins
boolean hasKotlinUltimate
LocalBuildProperties(Settings settings) {
propertiesProvider = new LocalBuildPropertiesProvider(settings)
includeCidrPlugins = propertiesProvider.getBoolean('cidrPluginsEnabled') && new File(propertiesProvider.rootProjectDir, 'kotlin-ultimate').exists()
hasKotlinUltimate = new File(propertiesProvider.rootProjectDir, 'kotlin-ultimate').exists()
includeCidrPlugins = propertiesProvider.getBoolean('cidrPluginsEnabled') && hasKotlinUltimate
}
}
+5 -3
View File
@@ -57,9 +57,7 @@ class KotlinBuildProperties(
val useBootstrapStdlib: Boolean
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
val kotlinUltimateExists: Boolean = propertiesProvider.rootProjectDir.resolve("kotlin-ultimate").exists()
val includeCidrPlugins: Boolean = kotlinUltimateExists && getBoolean("cidrPluginsEnabled")
private val kotlinUltimateExists: Boolean = propertiesProvider.rootProjectDir.resolve("kotlin-ultimate").exists()
val isTeamcityBuild: Boolean = getBoolean("teamcity") || System.getenv("TEAMCITY_VERSION") != null
@@ -72,6 +70,10 @@ class KotlinBuildProperties(
return kotlinUltimateExists && (explicitlyEnabled || isTeamcityBuild)
}
val includeCidrPlugins: Boolean = kotlinUltimateExists && getBoolean("cidrPluginsEnabled")
val includeUltimate: Boolean = kotlinUltimateExists && (isTeamcityBuild || intellijUltimateEnabled)
val postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
val relocation: Boolean get() = postProcessing
@@ -57,6 +57,8 @@ var DataNode<out ModuleData>.isHmpp
by NotNullableCopyableDataNodeUserDataProperty(Key.create<Boolean>("IS_HMPP_MODULE"), false)
var DataNode<ModuleData>.platformPluginId
by CopyableDataNodeUserDataProperty(Key.create<String>("PLATFORM_PLUGIN_ID"))
var DataNode<ModuleData>.kotlinNativeHome
by CopyableDataNodeUserDataProperty(Key.create<String>("KOTLIN_NATIVE_HOME"))
var DataNode<out ModuleData>.implementedModuleNames
by NotNullableCopyableDataNodeUserDataProperty(Key.create<List<String>>("IMPLEMENTED_MODULE_NAME"), emptyList())
// Project is usually the same during all import, thus keeping Map Project->Dependencies makes model a bit more complicated but allows to avoid future problems
@@ -15,10 +15,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.util.Key
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.gradle.KotlinModule
import org.jetbrains.kotlin.gradle.KotlinPlatform
import org.jetbrains.kotlin.gradle.KotlinPlatformContainer
import org.jetbrains.kotlin.gradle.KotlinPlatformContainerImpl
import org.jetbrains.kotlin.gradle.*
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File
@@ -59,6 +56,7 @@ class KotlinAndroidSourceSetData(
class KotlinTargetData(name: String) : AbstractNamedData(GradleConstants.SYSTEM_ID, name) {
var moduleIds: Set<String> = emptySet()
var archiveFile: File? = null
var konanArtifacts: Collection<KonanArtifactModel>? = null
companion object {
val KEY = ExternalKey.create(KotlinTargetData::class.java, ProjectKeys.MODULE.processingWeight + 1)
@@ -206,6 +206,8 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
val mppModel = resolverCtx.getMppModel(gradleModule)
if (mppModel == null || externalProject == null) return
mainModuleNode.kotlinNativeHome = mppModel.kotlinNativeHome
val jdkName = gradleModule.jdkNameIfAny
// save artefacts locations.
@@ -244,6 +246,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
if (target.name == KotlinTarget.METADATA_TARGET_NAME) continue
val targetData = KotlinTargetData(target.name).also {
it.archiveFile = target.jar?.archiveFile
it.konanArtifacts = target.konanArtifacts
}
val targetDataNode = mainModuleNode.createChild<KotlinTargetData>(KotlinTargetData.KEY, targetData)
@@ -119,7 +119,7 @@ enum class KotlinPlatform(val id: String) {
}
}
interface KotlinPlatformContainer: Serializable {
interface KotlinPlatformContainer : Serializable {
val platforms: Collection<KotlinPlatform>
fun supports(simplePlatform: KotlinPlatform): Boolean
@@ -142,6 +142,7 @@ interface KotlinTarget : Serializable {
val compilations: Collection<KotlinCompilation>
val testTasks: Collection<KotlinTestTask>
val jar: KotlinTargetJar?
val konanArtifacts: List<KonanArtifactModel>
companion object {
const val METADATA_TARGET_NAME = "metadata"
@@ -167,4 +168,29 @@ interface KotlinMPPGradleModel : Serializable {
companion object {
const val NO_KOTLIN_NATIVE_HOME = ""
}
}
}
interface KonanArtifactModel : Serializable {
val targetName: String
val executableName: String
val type: String // represents org.jetbrains.kotlin.konan.target.CompilerOutputKind
val targetPlatform: String
val file: File
val buildTaskPath: String
val runConfiguration: KonanRunConfigurationModel
val isTests: Boolean
}
interface KonanRunConfigurationModel : Serializable {
val workingDirectory: String
val programParameters: List<String>
val environmentVariables: Map<String, String>
fun isNotEmpty() = workingDirectory.isNotEmpty() || programParameters.isNotEmpty() || environmentVariables.isNotEmpty()
companion object {
const val NO_WORKING_DIRECTORY = ""
val NO_PROGRAM_PARAMETERS = emptyList<String>()
val NO_ENVIRONMENT_VARIABLES = emptyMap<String, String>()
}
}
@@ -13,6 +13,8 @@ import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.logging.Logging
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Exec
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel.Companion.NO_KOTLIN_NATIVE_HOME
import org.jetbrains.plugins.gradle.model.*
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
@@ -218,6 +220,53 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
return project.getTargets()?.mapNotNull { buildTarget(it, sourceSetMap, dependencyResolver, project, dependencyMapper) }
}
private operator fun Any?.get(methodName: String, vararg params: Any): Any? {
return this[methodName, params.map { it.javaClass }, params.toList()]
}
private operator fun Any?.get(methodName: String, paramTypes: List<Class<*>>, params: List<Any?>): Any? {
if (this == null) return null
return this::class.java.getMethodOrNull(methodName, *paramTypes.toTypedArray())?.invoke(this, *params.toTypedArray())
}
private fun buildArtifact(
executableName: String,
linkTask: Task,
runConfiguration: KonanRunConfigurationModel
): KonanArtifactModel? {
val outputKind = linkTask["getOutputKind"]["name"] as? String ?: return null
val konanTargetName = linkTask["getTarget"] as? String ?: error("No arch target found")
val outputFile = (linkTask["getOutputFile"] as? Provider<*>)?.orNull as? File ?: return null
val compilationTarget = linkTask["getCompilation"]["getTarget"]
val compilationTargetName = compilationTarget["getName"] as? String ?: return null
val isTests = linkTask["getProcessTests"] as? Boolean ?: return null
return KonanArtifactModelImpl(
compilationTargetName,
executableName,
outputKind,
konanTargetName,
outputFile,
linkTask.path,
runConfiguration,
isTests
)
}
private fun konanArtifacts(target: Named): List<KonanArtifactModel> {
val result = ArrayList<KonanArtifactModel>()
val binaries = target["getBinaries"] as? Collection<*> ?: return result
binaries.forEach { binary ->
val executableName = binary["getBaseName"] as? String ?: ""
val linkTask = binary["getLinkTask"] as? Task ?: return@forEach
val runConfiguration = KonanRunConfigurationModelImpl(binary["getRunTask"] as? Exec)
buildArtifact(executableName, linkTask, runConfiguration)?.let { result.add(it) }
}
return result
}
private fun buildTarget(
gradleTarget: Named,
sourceSetMap: Map<String, KotlinSourceSet>,
@@ -247,7 +296,17 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
}
val jar = buildTargetJar(gradleTarget, project)
val testTasks = buildTestTasks(project, gradleTarget)
val target = KotlinTargetImpl(gradleTarget.name, targetPresetName, disambiguationClassifier, platform, compilations, testTasks, jar)
val artifacts = konanArtifacts(gradleTarget)
val target = KotlinTargetImpl(
gradleTarget.name,
targetPresetName,
disambiguationClassifier,
platform,
compilations,
testTasks,
jar,
artifacts
)
compilations.forEach {
it.disambiguationClassifier = target.disambiguationClassifier
it.platform = target.platform
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.tasks.Exec
import java.io.File
import kotlin.collections.HashSet
@@ -133,7 +134,8 @@ data class KotlinTargetImpl(
override val platform: KotlinPlatform,
override val compilations: Collection<KotlinCompilation>,
override val testTasks: Collection<KotlinTestTask>,
override val jar: KotlinTargetJar?
override val jar: KotlinTargetJar?,
override val konanArtifacts: List<KonanArtifactModel>
) : KotlinTarget {
override fun toString() = name
@@ -152,7 +154,8 @@ data class KotlinTargetImpl(
cloningCache[initialTestTask] = it
}
},
KotlinTargetJarImpl(target.jar?.archiveFile)
KotlinTargetJarImpl(target.jar?.archiveFile),
target.konanArtifacts.map { KonanArtifactModelImpl(it) }.toList()
)
}
@@ -209,3 +212,44 @@ class KotlinPlatformContainerImpl() : KotlinPlatformContainer {
(myPlatforms ?: HashSet<KotlinPlatform>().apply { myPlatforms = this }).addAll(platforms)
}
}
data class KonanArtifactModelImpl(
override val targetName: String,
override val executableName: String,
override val type: String,
override val targetPlatform: String,
override val file: File,
override val buildTaskPath: String,
override val runConfiguration: KonanRunConfigurationModel,
override val isTests: Boolean
) : KonanArtifactModel {
constructor(artifact: KonanArtifactModel) : this(
artifact.targetName,
artifact.executableName,
artifact.type,
artifact.targetPlatform,
artifact.file,
artifact.buildTaskPath,
KonanRunConfigurationModelImpl(artifact.runConfiguration),
artifact.isTests
)
}
data class KonanRunConfigurationModelImpl(
override val workingDirectory: String,
override val programParameters: List<String>,
override val environmentVariables: Map<String, String>
) : KonanRunConfigurationModel {
constructor(configuration: KonanRunConfigurationModel) : this(
configuration.workingDirectory,
ArrayList(configuration.programParameters),
HashMap(configuration.environmentVariables)
)
constructor(runTask: Exec?) : this(
runTask?.workingDir?.path ?: KonanRunConfigurationModel.NO_WORKING_DIRECTORY,
runTask?.args as List<String>? ?: KonanRunConfigurationModel.NO_PROGRAM_PARAMETERS,
(runTask?.environment as Map<String, Any>?)
?.mapValues { it.value.toString() } ?: KonanRunConfigurationModel.NO_ENVIRONMENT_VARIABLES
)
}
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.gradle
import org.gradle.api.Project
// KT-29613, KT-29783
internal object KotlinNativeHomeEvaluator {
object KotlinNativeHomeEvaluator {
private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome"
private const val FALLBACK_ACCESSOR_CLASS = "org.jetbrains.kotlin.compilerRunner.KotlinNativeToolRunnerKt"
private const val FALLBACK_ACCESSOR_METHOD = "getKonanHome"
internal fun getKotlinNativeHome(project: Project): String? =
fun getKotlinNativeHome(project: Project): String? =
getKotlinNativeHomePrimary(project) ?: getKotlinNativeHomeFallback(project)
// Read Kotlin/Native home from the predefined property in Gradle plugin.
+7 -7
View File
@@ -226,7 +226,8 @@ def flags = BuildPropertiesKt.getKotlinBuildPropertiesForSettings(settings)
if (flags.includeCidrPlugins) {
logger.info("Including CIDR plugins in settings.gradle")
include ":kotlin-ultimate:ide:cidr-native",
include ":kotlin-ultimate:ide:common-native",
":kotlin-ultimate:ide:cidr-native",
":kotlin-ultimate:ide:clion-native",
":kotlin-ultimate:ide:appcode-native",
":kotlin-ultimate:prepare:cidr-plugin",
@@ -236,12 +237,11 @@ if (flags.includeCidrPlugins) {
logger.info("NOT including CIDR plugins in settings.gradle")
}
def isTeamcityBuild = hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
if (flags.kotlinUltimateExists && (isTeamcityBuild || flags.intellijUltimateEnabled)) {
include(
":kotlin-ultimate:ultimate",
":kotlin-ultimate:ultimate:ultimate-runner"
)
if (flags.includeUltimate) {
include ":kotlin-ultimate:ultimate",
":kotlin-ultimate:ultimate:ultimate-runner",
":kotlin-ultimate:ide:common-native",
":kotlin-ultimate:ide:ultimate-native"
logger.info("Including extension for IJ Ultimate in settings.gradle")
} else {
logger.info("NOT including extension for IJ Ultimate in settings.gradle")