Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IC for Compose Wasm #775

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@ allprojects {
maven("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental")
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
afterEvaluate {
dependencies {
dependencies {
}

setOf(
rootProject,
project(":common"),
project(":executors"),
project(":indexation"),
).forEach { project ->
project.afterEvaluate {
project.dependencies {
project.dependencies {
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2")
implementation(libs.kotlin.idea) {
isTransitive = false
Expand All @@ -58,6 +66,39 @@ val resourceDependency: Configuration by configurations.creating {
isCanBeConsumed = false
}


val kotlinComposeWasmIcLocalCache: Configuration by configurations.creating {
isTransitive = false
isCanBeResolved = true
isCanBeConsumed = false
attributes {
attribute(
Category.CATEGORY_ATTRIBUTE,
objects.categoryComposeCache
)
attribute(
CacheAttribute.cacheAttribute,
CacheAttribute.LOCAL
)
}
}

val kotlinComposeWasmIcLambdaCache: Configuration by configurations.creating {
isTransitive = false
isCanBeResolved = true
isCanBeConsumed = false
attributes {
attribute(
Category.CATEGORY_ATTRIBUTE,
objects.categoryComposeCache
)
attribute(
CacheAttribute.cacheAttribute,
CacheAttribute.LAMBDA
)
}
}

dependencies {
annotationProcessor("org.springframework:spring-context-indexer")
implementation("com.google.code.gson:gson")
Expand Down Expand Up @@ -85,6 +126,9 @@ dependencies {
testImplementation(libs.kotlinx.coroutines.test)

resourceDependency(libs.skiko.js.wasm.runtime)

kotlinComposeWasmIcLocalCache(project(":cache-maker"))
kotlinComposeWasmIcLambdaCache(project(":cache-maker"))
}

fun buildPropertyFile() {
Expand All @@ -109,6 +153,7 @@ fun generateProperties(prefix: String = "") = """
libraries.folder.compose-wasm=${prefix + libComposeWasm}
libraries.folder.compose-wasm-compiler-plugins=${prefix + libComposeWasmCompilerPlugins}
libraries.folder.compiler-plugins=${prefix + compilerPluginsForJVM}
caches.folder.compose-wasm=${prefix + cachesComposeWasm}
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
server.compression.enabled=true
server.compression.mime-types=application/json,text/javascript,application/wasm
Expand All @@ -120,6 +165,7 @@ tasks.withType<KotlinCompile> {
}
dependsOn(":executors:jar")
dependsOn(":indexation:run")
dependsOn(kotlinComposeWasmIcLocalCache)
buildPropertyFile()
}
println("Using Kotlin compiler ${libs.versions.kotlin.get()}")
Expand All @@ -131,7 +177,7 @@ tasks.withType<BootJar> {

val buildLambda by tasks.creating(Zip::class) {
val propertyFile = propertyFile
val propertyFileContent = generateProperties("/var/task/")
val propertyFileContent = generateProperties(lambdaPrefix)

from(tasks.compileKotlin)
from(tasks.processResources) {
Expand All @@ -152,6 +198,7 @@ val buildLambda by tasks.creating(Zip::class) {
from(libJVMFolder) { into(libJVM) }
from(compilerPluginsForJVMFolder) {into(compilerPluginsForJVM)}
from(libComposeWasmCompilerPluginsFolder) { into(libComposeWasmCompilerPlugins) }
from(kotlinComposeWasmIcLambdaCache)
into("lib") {
from(configurations.compileClasspath) { exclude("tomcat-embed-*") }
}
Expand Down
10 changes: 10 additions & 0 deletions buildSrc/src/main/kotlin/CacheAttribute.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import org.gradle.api.attributes.Attribute

enum class CacheAttribute {
LOCAL,
LAMBDA;

companion object {
val cacheAttribute = Attribute.of("org.jetbrains.kotlin-compiler-server.cache", CacheAttribute::class.java)
}
}
5 changes: 5 additions & 0 deletions buildSrc/src/main/kotlin/CategoryAttribute.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import org.gradle.api.attributes.Category
import org.gradle.api.model.ObjectFactory

val ObjectFactory.categoryComposeCache
get() = named(Category::class.java, "compose-cache")
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/lambda.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val lambdaPrefix = "/var/task/"
9 changes: 7 additions & 2 deletions buildSrc/src/main/kotlin/properties.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Project
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.kotlin.dsl.the

val indexes: String by System.getProperties()
Expand All @@ -25,6 +25,8 @@ val Project.libComposeWasm
get() = "$kotlinVersion-compose-wasm"
val Project.libComposeWasmCompilerPlugins
get() = "$kotlinVersion-compose-wasm-compiler-plugins"
val Project.cachesComposeWasm
get() = "$kotlinVersion-caches-compose-wasm"

val Project.libJVMFolder
get() = rootProject.layout.projectDirectory.dir(libJVM)
Expand All @@ -42,4 +44,7 @@ val Project.libComposeWasmFolder
get() = rootProject.layout.projectDirectory.dir(libComposeWasm)

val Project.libComposeWasmCompilerPluginsFolder
get() = rootProject.layout.projectDirectory.dir(libComposeWasmCompilerPlugins)
get() = rootProject.layout.projectDirectory.dir(libComposeWasmCompilerPlugins)

val Project.cachesComposeWasmFolder
get() = rootProject.layout.projectDirectory.dir(cachesComposeWasm)
30 changes: 30 additions & 0 deletions cache-maker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM amazoncorretto:17

ARG BASE_DIR
ARG KOTLIN_VERSION

RUN if [ -z "$KOTLIN_VERSION" ]; then \
echo "Error: KOTLIN_VERSION argument is not set. Use docker-build-incremental-cache.sh to build the image." >&2; \
exit 1; \
fi

ENV KOTLIN_LIB=$KOTLIN_VERSION
ENV KOTLIN_LIB_JS=${KOTLIN_VERSION}-js
ENV KOTLIN_LIB_WASM=${KOTLIN_VERSION}-wasm
ENV KOTLIN_LIB_COMPOSE_WASM=${KOTLIN_VERSION}-compose-wasm
ENV KOTLIN_COMPOSE_WASM_COMPILER_PLUGINS=${KOTLIN_VERSION}-compose-wasm-compiler-plugins
ENV KOTLIN_CACHES_COMPOSE_WASM=${KOTLIN_VERSION}-caches-compose-wasm

RUN mkdir -p $BASE_DIR
WORKDIR $BASE_DIR
ADD . $BASE_DIR

RUN rm -rf $KOTLIN_LIB
RUN rm -rf $KOTLIN_LIB_JS
RUN rm -rf $KOTLIN_LIB_WASM
RUN rm -rf $KOTLIN_LIB_COMPOSE_WASM
RUN rm -rf $KOTLIN_COMPOSE_WASM_COMPILER_PLUGINS
RUN rm -rf $KOTLIN_CACHES_COMPOSE_WASM
RUN ./gradlew clean

RUN ./gradlew :cache-maker:run
91 changes: 91 additions & 0 deletions cache-maker/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
plugins {
kotlin("jvm")
application
}

dependencies {
implementation(project(":common", configuration = "default"))
}

application {
mainClass.set("com.compiler.server.cache.MainKt")
}

val runTask = tasks.named<JavaExec>("run") {
dependsOn(":dependencies:copyDependencies")
dependsOn(":dependencies:copyWasmDependencies")
dependsOn(":dependencies:copyComposeWasmCompilerPlugins")
dependsOn(":dependencies:copyComposeWasmDependencies")

val kotlinVersion = libs.versions.kotlin.get()
inputs.property("kotlinVersion", kotlinVersion)

inputs.dir(libWasmFolder)
inputs.dir(libComposeWasmFolder)
inputs.dir(libComposeWasmCompilerPluginsFolder)

outputs.dir(cachesComposeWasmFolder)

args(
kotlinVersion,
libJVMFolder.asFile.absolutePath,
cachesComposeWasmFolder,
)
}

val outputLambdaCacheDir: Provider<Directory> = layout.buildDirectory.dir("incremental-cache")
val buildCacheForLambda by tasks.registering(Exec::class) {
workingDir = rootDir
executable = "${project.name}/docker-build-incremental-cache.sh"

val outputDir = outputLambdaCacheDir

outputs.dir(outputDir.map { it.dir(cachesComposeWasm) })

argumentProviders.add {
listOf(
lambdaPrefix, // baseDir
outputDir.get().asFile.normalize().absolutePath, // targetDir
)
}
}

val kotlinComposeWasmIc: Configuration by configurations.creating {
isTransitive = false
isCanBeResolved = false
isCanBeConsumed = true
attributes {
attribute(
Category.CATEGORY_ATTRIBUTE,
objects.categoryComposeCache
)
}
}

kotlinComposeWasmIc.outgoing.variants.create("local") {
attributes {
attribute(
CacheAttribute.cacheAttribute,
CacheAttribute.LOCAL
)
}

artifact(cachesComposeWasmFolder) {
type = "directory"
builtBy(runTask)
}
}

kotlinComposeWasmIc.outgoing.variants.create("lambda") {
attributes {
attribute(
CacheAttribute.cacheAttribute,
CacheAttribute.LAMBDA
)
}

artifact(outputLambdaCacheDir) {
type = "directory"
builtBy(buildCacheForLambda)
}
}
24 changes: 24 additions & 0 deletions cache-maker/docker-build-incremental-cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh

kotlinVersion=$(awk '{ if ($1 == "kotlin") { gsub(/"/, "", $2); print $2; } }' FS=' = ' ./gradle/libs.versions.toml)

baseDir=$1
targetDir=$2

echo "Kotlin Version for the docker: $kotlinVersion"
echo "Base directory: $baseDir"
echo "Target directory: $targetDir"

image_tag=my-image-name:$(date +%s)

docker build . --file cache-maker/Dockerfile --tag $image_tag --build-arg BASE_DIR=$baseDir --build-arg KOTLIN_VERSION=$kotlinVersion

container=$(docker create $image_tag)

docker cp $container:$baseDir/$kotlinVersion-caches-compose-wasm $targetDir

docker start $container
docker stop $container
docker remove $container

docker rmi $image_tag
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.compiler.server.cache

import com.compiler.server.common.components.KotlinEnvironment
import com.compiler.server.common.components.compileWasmArgs
import com.compiler.server.common.components.linkWasmArgs
import com.compiler.server.common.components.usingTempDirectory
import org.jetbrains.kotlin.cli.common.CLICompiler.Companion.doMainNoExit
import org.jetbrains.kotlin.cli.js.K2JSCompiler
import java.io.File
import kotlin.io.path.div


class CacheBuilder(
private val kotlinEnvironment: KotlinEnvironment,
) {
fun compileCache(outputForCache: String) {
val moduleName = "playground"
usingTempDirectory { outputDir ->
val resource = this::class.java.classLoader.getResource("File.kt")!!.path

val klibPath = (outputDir / "klib").toFile().normalize().absolutePath

val k2JSCompiler = K2JSCompiler()

doMainNoExit(
k2JSCompiler,
compileWasmArgs(
moduleName,
listOf(resource),
klibPath,
kotlinEnvironment.COMPOSE_WASM_COMPILER_PLUGINS,
kotlinEnvironment.composeWasmCompilerPluginOptions,
kotlinEnvironment.COMPOSE_WASM_LIBRARIES
).toTypedArray()
)

usingTempDirectory { tmpDir ->
val cachesDir = tmpDir.resolve("caches").normalize()
doMainNoExit(
k2JSCompiler,
linkWasmArgs(
moduleName,
klibPath,
kotlinEnvironment.COMPOSE_WASM_LIBRARIES,
cachesDir.normalize(),
outputDir,
false
).toTypedArray()
)

cachesDir.toFile().copyRecursively(File(outputForCache), overwrite = true)
}
}
}
}
14 changes: 14 additions & 0 deletions cache-maker/src/main/kotlin/com/compiler/server/cache/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.compiler.server.cache

import com.compiler.server.common.components.KotlinEnvironmentConfiguration

fun main(args: Array<String>) {
val version = args[0]
val directory = args[1]
val outputPathCacheComposeWasm = args[2]
val kotlinEnvironment = KotlinEnvironmentConfiguration(version, directory).kotlinEnvironment

CacheBuilder(
kotlinEnvironment = kotlinEnvironment
).compileCache(outputPathCacheComposeWasm)
}
Loading
Loading