mirror of
https://github.com/jlengrand/compose-multiplatform.git
synced 2026-03-10 08:11:20 +00:00
Support Kotlin JS targets in Compose Gradle plugin
This commit is contained in:
committed by
Alexey Tsvetkov
parent
cab2ac642e
commit
7a47ba8dd8
@@ -17,4 +17,6 @@ object BuildProperties {
|
||||
fun deployVersion(project: Project): String =
|
||||
System.getenv("COMPOSE_GRADLE_PLUGIN_VERSION")
|
||||
?: project.findProperty("deploy.version") as String
|
||||
fun isComposeWithWeb(project: Project): Boolean =
|
||||
project.findProperty("compose.with.web") == "true"
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ buildConfig {
|
||||
packageName = "org.jetbrains.compose"
|
||||
clsName = "ComposeBuildConfig"
|
||||
buildConfigField("String", "composeVersion", BuildProperties.composeVersion(project))
|
||||
buildConfigField("Boolean", "isComposeWithWeb", BuildProperties.isComposeWithWeb(project).toString())
|
||||
}
|
||||
|
||||
val embedded by configurations.creating
|
||||
|
||||
@@ -6,23 +6,48 @@
|
||||
package org.jetbrains.compose
|
||||
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.compose.internal.webExt
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
||||
|
||||
class ComposeCompilerKotlinSupportPlugin : KotlinCompilerPluginSupportPlugin {
|
||||
override fun getCompilerPluginId(): String =
|
||||
"org.jetbrains.compose"
|
||||
"androidx.compose.compiler.plugins.kotlin"
|
||||
|
||||
override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean {
|
||||
val targetPlatform = kotlinCompilation.target.platformType
|
||||
return targetPlatform != KotlinPlatformType.js
|
||||
&& targetPlatform != KotlinPlatformType.native
|
||||
override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean =
|
||||
when (kotlinCompilation.target.platformType) {
|
||||
KotlinPlatformType.common -> true
|
||||
KotlinPlatformType.jvm -> true
|
||||
KotlinPlatformType.js -> isApplicableJsTarget(kotlinCompilation.target)
|
||||
KotlinPlatformType.androidJvm -> true
|
||||
KotlinPlatformType.native -> false
|
||||
}
|
||||
|
||||
override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>): Provider<List<SubpluginOption>> {
|
||||
val target = kotlinCompilation.target
|
||||
return target.project.provider {
|
||||
platformPluginOptions[target.platformType] ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>): Provider<List<SubpluginOption>> =
|
||||
kotlinCompilation.target.project.provider { emptyList() }
|
||||
|
||||
override fun getPluginArtifact(): SubpluginArtifact =
|
||||
SubpluginArtifact(
|
||||
groupId = "org.jetbrains.compose.compiler", artifactId = "compiler", version = composeVersion
|
||||
)
|
||||
|
||||
private fun isApplicableJsTarget(kotlinTarget: KotlinTarget): Boolean {
|
||||
if (kotlinTarget !is KotlinJsIrTarget) return false
|
||||
|
||||
val project = kotlinTarget.project
|
||||
val webExt = project.webExt ?: return false
|
||||
|
||||
return kotlinTarget in webExt.targetsToConfigure(project)
|
||||
}
|
||||
|
||||
private val platformPluginOptions = mapOf(
|
||||
KotlinPlatformType.js to options("generateDecoys" to "true")
|
||||
)
|
||||
|
||||
private fun options(vararg options: Pair<String, String>): List<SubpluginOption> =
|
||||
options.map { SubpluginOption(it.first, it.second) }
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.compose.desktop.DesktopExtension
|
||||
import org.jetbrains.compose.desktop.application.internal.configureApplicationImpl
|
||||
import org.jetbrains.compose.desktop.application.internal.currentTarget
|
||||
import org.jetbrains.compose.desktop.preview.internal.initializePreview
|
||||
import org.jetbrains.compose.web.internal.initializeWeb
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
@@ -37,8 +38,11 @@ class ComposePlugin : Plugin<Project> {
|
||||
}
|
||||
|
||||
project.initializePreview()
|
||||
if (ComposeBuildConfig.isComposeWithWeb) {
|
||||
project.initializeWeb(composeExtension)
|
||||
}
|
||||
|
||||
project.pluginManager.apply(ComposeCompilerKotlinSupportPlugin::class.java)
|
||||
project.plugins.apply(ComposeCompilerKotlinSupportPlugin::class.java)
|
||||
|
||||
project.afterEvaluate {
|
||||
if (desktopExtension._isApplicationInitialized) {
|
||||
@@ -112,6 +116,9 @@ class ComposePlugin : Plugin<Project> {
|
||||
val runtime get() = composeDependency("org.jetbrains.compose.runtime:runtime")
|
||||
val ui get() = composeDependency("org.jetbrains.compose.ui:ui")
|
||||
val materialIconsExtended get() = composeDependency("org.jetbrains.compose.material:material-icons-extended")
|
||||
val web: WebDependencies =
|
||||
if (ComposeBuildConfig.isComposeWithWeb) WebDependencies
|
||||
else error("This version of Compose plugin does not support 'compose.web.*' dependencies")
|
||||
}
|
||||
|
||||
object DesktopDependencies {
|
||||
@@ -141,6 +148,12 @@ class ComposePlugin : Plugin<Project> {
|
||||
composeDependency("org.jetbrains.compose.desktop:desktop-jvm-${currentTarget.id}")
|
||||
}
|
||||
}
|
||||
|
||||
object WebDependencies {
|
||||
val web by lazy {
|
||||
composeDependency("org.jetbrains.compose.web:web")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinDependencyHandler.compose(groupWithArtifact: String) = composeDependency(groupWithArtifact)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.compose.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.compose.ComposeExtension
|
||||
import org.jetbrains.compose.web.WebExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
|
||||
internal val Project.composeExt: ComposeExtension?
|
||||
get() = extensions.findByType(ComposeExtension::class.java)
|
||||
|
||||
internal val Project.webExt: WebExtension?
|
||||
get() = composeExt?.extensions?.findByType(WebExtension::class.java)
|
||||
|
||||
internal val Project.mppExt: KotlinMultiplatformExtension?
|
||||
get() = extensions.findByType(KotlinMultiplatformExtension::class.java)
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.compose.web
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ExtensionAware
|
||||
import org.jetbrains.compose.internal.mppExt
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
||||
|
||||
abstract class WebExtension : ExtensionAware {
|
||||
private var requestedTargets: Set<KotlinJsIrTarget>? = null
|
||||
private var targetsToConfigure: Set<KotlinJsIrTarget>? = null
|
||||
|
||||
// public api
|
||||
@Suppress("unused")
|
||||
fun targets(vararg targets: KotlinTarget) {
|
||||
check(requestedTargets == null) {
|
||||
"compose.web.targets() was already set!"
|
||||
}
|
||||
|
||||
val jsIrTargets = linkedSetOf<KotlinJsIrTarget>()
|
||||
for (target in targets) {
|
||||
check(target is KotlinJsIrTarget) {
|
||||
"""|'${target.name}' is not a JS(IR) target:
|
||||
|* add `kotlin.js.compiler=ir` to gradle properties;
|
||||
|* define target as `kotlin { js(IR) { ... } }`
|
||||
""".trimMargin()
|
||||
}
|
||||
jsIrTargets.add(target)
|
||||
}
|
||||
requestedTargets = jsIrTargets
|
||||
}
|
||||
|
||||
internal fun targetsToConfigure(project: Project): Set<KotlinJsIrTarget> {
|
||||
targetsToConfigure =
|
||||
targetsToConfigure
|
||||
?: requestedTargets
|
||||
?: defaultJsTargetsToConfigure(project)
|
||||
|
||||
return targetsToConfigure!!
|
||||
}
|
||||
|
||||
private fun defaultJsTargetsToConfigure(project: Project): Set<KotlinJsIrTarget> {
|
||||
val mppTargets = project.mppExt?.targets?.asMap?.values ?: emptySet()
|
||||
val jsIRTargets = mppTargets.filterIsInstanceTo(LinkedHashSet<KotlinJsIrTarget>())
|
||||
|
||||
return if (jsIRTargets.size > 1) {
|
||||
project.logger.error(
|
||||
"w: Default configuration for Compose Web is disabled: " +
|
||||
"multiple Kotlin JS IR targets are defined. " +
|
||||
"Specify Compose Web Kotlin targets by using `compose.web.targets()`"
|
||||
)
|
||||
emptySet()
|
||||
} else jsIRTargets
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.compose.web.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.compose.ComposeExtension
|
||||
import org.jetbrains.compose.web.WebExtension
|
||||
|
||||
internal fun Project.initializeWeb(composeExtension: ComposeExtension) {
|
||||
project.plugins.withId("org.jetbrains.kotlin.multiplatform") {
|
||||
composeExtension.extensions.create("web", WebExtension::class.java)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ kotlin.code.style=official
|
||||
#
|
||||
# __LATEST_COMPOSE_RELEASE_VERSION__
|
||||
compose.version=0.4.0-build182
|
||||
compose.with.web=false
|
||||
|
||||
# A version of Gradle plugin, that will be published,
|
||||
# unless overridden by COMPOSE_GRADLE_PLUGIN_VERSION env var.
|
||||
|
||||
Reference in New Issue
Block a user