| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import androidx.build.LibraryGroups |
| import androidx.build.LibraryVersions |
| import androidx.build.Publish |
| import java.nio.file.Files |
| import java.nio.file.Paths |
| import java.nio.file.StandardCopyOption |
| import org.jetbrains.kotlin.gradle.tasks.KotlinCompile |
| |
| import com.android.build.api.attributes.BuildTypeAttr |
| import org.gradle.api.Project |
| import org.gradle.api.artifacts.Configuration |
| import org.gradle.api.attributes.Attribute |
| import org.gradle.api.attributes.Usage |
| import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType |
| import java.io.BufferedInputStream |
| import java.io.BufferedOutputStream |
| import java.io.File |
| import java.io.FileInputStream |
| import java.io.FileOutputStream |
| import java.nio.file.Files |
| import java.nio.file.StandardCopyOption |
| import java.util.zip.ZipEntry |
| import java.util.zip.ZipInputStream |
| |
| import static androidx.build.dependencies.DependenciesKt.* |
| |
| plugins { |
| id("AndroidXPlugin") |
| id("com.android.library") |
| id("AndroidXUiPlugin") |
| id("kotlin-multiplatform") |
| } |
| |
| repositories { |
| // To allow using local Skija build. |
| mavenLocal() |
| } |
| |
| |
| |
| configurations { |
| ui_components |
| compose_compiler_jar |
| } |
| |
| AttributeContainer attrContainer = configurations.ui_components.getAttributes(); |
| attrContainer.attribute( |
| BuildTypeAttr.ATTRIBUTE,project.getObjects().named(BuildTypeAttr.class, "release") |
| ) |
| attrContainer.attribute( |
| Usage.USAGE_ATTRIBUTE, project.getObjects().named(Usage.class, Usage.JAVA_RUNTIME) |
| ) |
| attrContainer.attribute( |
| Attribute.of("org.jetbrains.kotlin.platform.type", KotlinPlatformType.class), KotlinPlatformType.jvm |
| ) |
| |
| dependencies { |
| ui_components "androidx.lifecycle:lifecycle-common:2.3.0-alpha01" |
| ui_components "androidx.lifecycle:lifecycle-runtime:2.3.0-alpha01" |
| ui_components "androidx.core:core:1.2.0" |
| ui_components "androidx.arch.core:core-common:2.1.0" |
| ui_components "org.jogamp.jogl:jogl-all:2.4.0-rc-20200306" |
| ui_components "org.jogamp.jogl:jogl-all-natives-linux-amd64:2.4.0-rc-20200306" |
| ui_components "org.jogamp.jogl:jogl-all-natives-macosx-universal:2.4.0-rc-20200306" |
| ui_components "org.jogamp.gluegen:gluegen-rt:2.4.0-rc-20200306" |
| ui_components "org.jogamp.gluegen:gluegen-rt-natives-linux-amd64:2.4.0-rc-20200306" |
| ui_components "org.jogamp.gluegen:gluegen-rt-natives-macosx-universal:2.4.0-rc-20200306" |
| |
| compose_compiler_jar project(":compose:compose-compiler") |
| } |
| |
| dependencies { |
| kotlinPlugin project(path: ":compose:compose-compiler") |
| } |
| |
| def joglDir = "${project.rootDir}/ui-desktop/libs" |
| def androidxDir = "${project.rootDir}/ui-desktop/libs" |
| def composeClassDir = project.rootDir.absolutePath + "/ui-desktop/compose-libs/" |
| |
| kotlin { |
| jvm() |
| |
| sourceSets { |
| commonMain.dependencies { |
| api(KOTLIN_STDLIB_COMMON) |
| implementation project(":compose:compose-runtime") |
| } |
| |
| jvmMain { |
| } |
| |
| jvmMain.dependencies { |
| api(KOTLIN_STDLIB) |
| api(KOTLIN_COROUTINES_CORE) |
| |
| api "org.jetbrains.skija:skija:0.1.0" |
| |
| api project(":ui:ui-desktop:android-emu") |
| |
| api files("$joglDir/gluegen-rt.jar") |
| api files("$joglDir/jogl-all.jar") |
| |
| api fileTree(project.rootDir.absolutePath + "/ui-desktop/compose-libs") |
| |
| implementation files("$androidxDir/core-common-2.1.0.jar") |
| implementation "androidx.lifecycle:lifecycle-common:2.3.0-alpha01" |
| implementation "androidx.lifecycle:lifecycle-runtime:2.3.0-alpha01" |
| |
| implementation files("$joglDir/gluegen-rt-natives-macosx-universal.jar") |
| implementation files("$joglDir/jogl-all-natives-macosx-universal.jar") |
| |
| // TODO: this is a bit ugly. We introduce dependency here, but in fact |
| // manually copy it later, as run task will have .aar in the classpath. |
| implementation "androidx.core:core:1.0.0" |
| implementation "androidx.lifecycle:lifecycle-runtime:2.3.0-alpha01" |
| } |
| } |
| } |
| |
| def uiComponents = [ |
| "ui-android-view", |
| "ui-animation", |
| "ui-animation-core", |
| "ui-core", |
| "ui-foundation", |
| "ui-framework", |
| "ui-geometry", |
| "ui-graphics", |
| "ui-layout", |
| "ui-livedata", |
| "ui-material", |
| "ui-platform", |
| "ui-saved-instance-state", |
| "ui-test", |
| "ui-text", |
| "ui-text-android", |
| "ui-text-core", |
| "ui-tooling", |
| "ui-unit", |
| "ui-util", |
| "ui-vector" |
| ] |
| |
| def androidxComponents = [ |
| "core:core", |
| "lifecycle:lifecycle-runtime" |
| ] |
| |
| |
| def copyToJar(File source, File jar) { |
| |
| if(source.name.endsWith(".jar")) { |
| Files.copy(source.toPath(), jar.toPath(), StandardCopyOption.REPLACE_EXISTING) |
| return |
| } |
| |
| byte[] buffer = new byte[2048] |
| |
| FileInputStream fis = new FileInputStream(source) |
| BufferedInputStream bis = new BufferedInputStream(fis) |
| ZipInputStream stream = new ZipInputStream(bis) |
| ZipEntry entry = null |
| while ((entry = stream.getNextEntry()) != null) { |
| if(!entry.name.equals("classes.jar")) continue; |
| FileOutputStream fos = new FileOutputStream(jar) |
| BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.size()) |
| int len = 0 |
| while ((len = stream.read(buffer)) > 0) { |
| bos.write(buffer, 0, len) |
| } |
| bos.close() |
| fos.close() |
| } |
| stream.close() |
| bis.close() |
| fis.close() |
| } |
| |
| |
| // Find in dependencies first (BFS) task's output ending with `name`. |
| String findInDeps(Task root, String name) { |
| // Do BFS by deps. |
| def queue = new java.util.ArrayDeque<Task>() |
| queue.addLast(root) |
| while (queue.size() > 0) { |
| def task = queue.pop() |
| def classes = task.outputs.files.files.find { it.name.endsWith(name) } |
| if (classes != null) { |
| return classes.absolutePath |
| } |
| task.taskDependencies.getDependencies(task).each { |
| queue.addLast(it) |
| } |
| } |
| return null |
| } |
| |
| task extractJars { |
| doLast { |
| // Find all JAR files matching components. |
| file(composeClassDir).mkdir() |
| uiComponents.each { component -> |
| def depProject = project(":ui:" + component) |
| def task = depProject.tasks.named("assemble").get() |
| def srcJar = findInDeps(task, "classes.jar") |
| if (srcJar == null) { |
| throw new Error("cannot find classes.jar in "+ task) |
| } else { |
| def destJar = composeClassDir + component + ".jar" |
| Files.copy(Paths.get(srcJar), Paths.get(destJar), StandardCopyOption.REPLACE_EXISTING) |
| } |
| } |
| def frameworkProject = project(":ui:ui-framework") |
| def srcJar = findInDeps(frameworkProject.tasks.named("assemble").get(), "compose-compiler.jar") |
| if (srcJar == null) |
| throw new Error("cannot find compose-compiler.jar") |
| Files.copy(Paths.get(srcJar), |
| Paths.get(composeClassDir + "compose-compiler.jar"), StandardCopyOption.REPLACE_EXISTING) |
| |
| configurations.ui_components.getIncoming().artifactView( |
| { config -> |
| config.attributes({container -> |
| // ... container.attribute(Attribute.of("artifactType", String.class), "android-classes") |
| }) |
| }) |
| .getArtifacts().getArtifactFiles().each { component -> |
| copyToJar( |
| component, |
| Paths.get(composeClassDir + component.name+".jar").toFile() |
| ) |
| }; |
| } |
| } |
| |
| extractJars.configure { |
| uiComponents.each { component -> |
| extractJars.dependsOn(":ui:" + component + ":assemble") |
| } |
| } |
| |
| tasks.withType(KotlinCompile).configureEach { |
| dependsOn("extractJars") |
| kotlinOptions { |
| useIR = true |
| freeCompilerArgs += [ |
| // TODO: hack, apply compose plugin better. |
| "-Xplugin=${project.rootDir.absolutePath}/ui-desktop/compose-libs/compose-compiler.jar", |
| "-P", "plugin:androidx.compose.plugins.idea:enabled=true", |
| |
| ] |
| } |
| } |
| |
| task run(type: JavaExec) { |
| main = 'androidx.ui.desktop.example.MainKt' |
| def compilation = kotlin.jvm().compilations["main"] |
| classpath = compilation.output.allOutputs + compilation.runtimeDependencyFiles + |
| fileTree(composeClassDir) |
| } |