Unverified Commit 10a91fc9 authored by Clément de La Bourdonnaye's avatar Clément de La Bourdonnaye Committed by GitHub

Re-enable android build (bis) (#1047)

Follows up MR #1043 that got reverted, new changes also include
corrected signature configuration
parent 08c42f3b
...@@ -187,7 +187,7 @@ jobs: ...@@ -187,7 +187,7 @@ jobs:
run: | run: |
./gradlew --no-daemon --stacktrace --info -Pkotlin.native.cacheKind.linuxX64=none :skiko:publishToMavenLocal ./gradlew --no-daemon --stacktrace --info -Pkotlin.native.cacheKind.linuxX64=none :skiko:publishToMavenLocal
./gradlew --no-daemon --stacktrace --info :SkiaAwtSample:installDist ./gradlew --no-daemon --stacktrace --info :SkiaAwtSample:installDist
./gradlew --no-daemon -Pskiko.android.enabled=true :skiko:publishSkikoJvmRuntimeAndroidX64PublicationToMavenLocal :skiko:publishSkikoJvmRuntimeAndroidArm64PublicationToMavenLocal :skiko:publishAndroidPublicationToMavenLocal ./gradlew --no-daemon -Pskiko.android.enabled=true :skiko:publishSkikoJvmRuntimeAndroidX64PublicationToMavenLocal :skiko:publishSkikoJvmRuntimeAndroidArm64PublicationToMavenLocal :skiko:publishAndroidReleasePublicationToMavenLocal
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
name: 'Save test results as artifact' name: 'Save test results as artifact'
......
...@@ -6,7 +6,7 @@ buildscript { ...@@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
classpath("com.android.tools.build:gradle:7.0.2") classpath("com.android.tools.build:gradle:7.4.2")
} }
} }
...@@ -18,8 +18,8 @@ repositories { ...@@ -18,8 +18,8 @@ repositories {
} }
plugins { plugins {
id("com.android.application") version "7.0.2" id("com.android.application") version "7.4.2"
kotlin("android") version "1.8.0" kotlin("android") version "1.9.21"
} }
val skikoNativeX64 by configurations.creating val skikoNativeX64 by configurations.creating
...@@ -38,9 +38,13 @@ val unzipTaskArm64 = tasks.register("unzipNativeArm64", Copy::class) { ...@@ -38,9 +38,13 @@ val unzipTaskArm64 = tasks.register("unzipNativeArm64", Copy::class) {
from(skikoNativeArm64.map { zipTree(it) }) from(skikoNativeArm64.map { zipTree(it) })
} }
kotlin {
jvmToolchain(11)
}
android { android {
compileSdk = 31 compileSdk = 31
namespace = "org.jetbrains.skiko.sample"
defaultConfig { defaultConfig {
minSdk = 27 minSdk = 27
targetSdk = 31 targetSdk = 31
...@@ -67,9 +71,9 @@ android { ...@@ -67,9 +71,9 @@ android {
} }
var version = if (project.hasProperty("skiko.version")) { var version = if (project.hasProperty("skiko.version")) {
project.properties["skiko.version"] as String project.properties["skiko.version"] as String
} else { } else {
"0.0.0-SNAPSHOT" "0.0.0-SNAPSHOT"
} }
// ./gradlew -Pskiko.android.enabled=true \ // ./gradlew -Pskiko.android.enabled=true \
...@@ -84,11 +88,20 @@ dependencies { ...@@ -84,11 +88,20 @@ dependencies {
skikoNativeArm64("org.jetbrains.skiko:skiko-android-runtime-arm64:$version") skikoNativeArm64("org.jetbrains.skiko:skiko-android-runtime-arm64:$version")
} }
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile>().configureEach { tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>().configureEach {
dependsOn(unzipTaskX64) dependsOn(unzipTaskX64)
dependsOn(unzipTaskArm64) dependsOn(unzipTaskArm64)
} }
// SKIKO-934: we need to unpack these libraries before these are collected from android
// TODO the tasks we're actually targetting are mergeDebugJniLibFolders and mergeReleaseJniLibFolders,
// this adds unncessary dependencies
tasks.withType<com.android.build.gradle.tasks.MergeSourceSetFolders>()
.configureEach {
dependsOn(unzipTaskX64)
dependsOn(unzipTaskArm64)
}
tasks.withType<Copy> { tasks.withType<Copy> {
// This line needs to properly merge MANIFEST files from jars into dex // This line needs to properly merge MANIFEST files from jars into dex
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
......
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
package="org.jetbrains.skiko.sample">
<application <application
android:allowBackup="true" android:allowBackup="true"
......
...@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl ...@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
import tasks.configuration.* import tasks.configuration.*
import kotlin.collections.HashMap import kotlin.collections.HashMap
import declareSkiaTasks import declareSkiaTasks
import com.android.build.gradle.LibraryExtension
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
...@@ -14,6 +15,10 @@ plugins { ...@@ -14,6 +15,10 @@ plugins {
id("org.gradle.crypto.checksum") version "1.4.0" id("org.gradle.crypto.checksum") version "1.4.0"
} }
if (supportAndroid) {
apply<com.android.build.gradle.LibraryPlugin>()
}
apply<WasmImportsGeneratorCompilerPluginSupportPlugin>() apply<WasmImportsGeneratorCompilerPluginSupportPlugin>()
apply<WasmImportsGeneratorForTestCompilerPluginSupportPlugin>() apply<WasmImportsGeneratorForTestCompilerPluginSupportPlugin>()
...@@ -45,6 +50,7 @@ allprojects { ...@@ -45,6 +50,7 @@ allprojects {
repositories { repositories {
mavenCentral() mavenCentral()
google()
} }
kotlin { kotlin {
...@@ -60,17 +66,19 @@ kotlin { ...@@ -60,17 +66,19 @@ kotlin {
} }
if (supportAndroid) { if (supportAndroid) {
jvm("android") { androidTarget("android") {
withJava() // This line needs to add Java sources in src/androidMain/java publishLibraryVariants("release")
compilations.all { compilations.all {
kotlinOptions.jvmTarget = "1.8" kotlinOptions.jvmTarget = "1.8"
} }
// We need an additional attribute to distinguish between JVM variants.
// Keep the previously defined attribute that was used to distinguish JVM and android variant
attributes { attributes {
attributes.attribute(Attribute.of("ui", String::class.java), "android") attributes.attribute(Attribute.of("ui", String::class.java), "android")
} }
// TODO: seems incorrect. // TODO: seems incorrect.
generateVersion( OS.Android, Arch.Arm64, skiko) generateVersion( OS.Android, Arch.Arm64, skiko, "release")
} }
} }
...@@ -185,7 +193,6 @@ kotlin { ...@@ -185,7 +193,6 @@ kotlin {
val androidMain by getting { val androidMain by getting {
dependsOn(jvmMain) dependsOn(jvmMain)
dependencies { dependencies {
compileOnly(files(androidJar()))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
} }
} }
...@@ -206,7 +213,7 @@ kotlin { ...@@ -206,7 +213,7 @@ kotlin {
} }
if (supportAndroid) { if (supportAndroid) {
val androidTest by getting { val androidUnitTest by getting {
dependsOn(jvmTest) dependsOn(jvmTest)
} }
} }
...@@ -394,19 +401,37 @@ kotlin { ...@@ -394,19 +401,37 @@ kotlin {
} }
if (supportAndroid) { if (supportAndroid) {
// Android configuration, when available
configure<LibraryExtension> {
compileSdk = 31
namespace = "org.jetbrains.skiko"
defaultConfig.minSdk = 24
defaultConfig.targetSdk = 24
defaultConfig.javaCompileOptions
compileOptions.sourceCompatibility = JavaVersion.VERSION_1_8
compileOptions.targetCompatibility = JavaVersion.VERSION_1_8
sourceSets.named("main") {
java.srcDirs("src/androidMain/java")
res.srcDirs("src/androidMain/res")
}
}
val os = OS.Android val os = OS.Android
val skikoAndroidJar by project.tasks.registering(Jar::class) { val skikoAndroidJar by project.tasks.registering(Jar::class) {
archiveBaseName.set("skiko-android") archiveBaseName.set("skiko-android")
from(kotlin.jvm("android").compilations["main"].output.allOutputs) from(kotlin.androidTarget("android").compilations["release"].output.allOutputs)
} }
for (arch in arrayOf(Arch.X64, Arch.Arm64)) { for (arch in arrayOf(Arch.X64, Arch.Arm64)) {
skikoProjectContext.createSkikoJvmJarTask(os, arch, skikoAndroidJar) skikoProjectContext.createSkikoJvmJarTask(os, arch, skikoAndroidJar)
} }
tasks.getByName("publishAndroidPublicationToMavenLocal") { tasks.matching { name == "publishAndroidReleasePublicationToMavenLocal" }.configureEach {
// It needs to be compatible with Gradle 8.1 // It needs to be compatible with Gradle 8.1
dependsOn(skikoAndroidJar) dependsOn(skikoAndroidJar)
} }
tasks.getByName("generateMetadataFileForAndroidPublication") { tasks.matching { name == "generateMetadataFileForAndroidReleasePublication" }.configureEach {
// It needs to be compatible with Gradle 8.1 // It needs to be compatible with Gradle 8.1
dependsOn(skikoAndroidJar) dependsOn(skikoAndroidJar)
} }
...@@ -556,6 +581,10 @@ publishing { ...@@ -556,6 +581,10 @@ publishing {
} }
} }
if (supportAndroid) {
pomNameForPublication["androidRelease"] = "Skiko Android Runtime"
}
val publicationsWithoutPomNames = publications.filter { it.name !in pomNameForPublication } val publicationsWithoutPomNames = publications.filter { it.name !in pomNameForPublication }
if (publicationsWithoutPomNames.isNotEmpty()) { if (publicationsWithoutPomNames.isNotEmpty()) {
error("Publications with unknown POM names: ${publicationsWithoutPomNames.joinToString { "'$it'" }}") error("Publications with unknown POM names: ${publicationsWithoutPomNames.joinToString { "'$it'" }}")
......
...@@ -111,8 +111,7 @@ fun skiaPreprocessorFlags(os: OS, buildType: SkiaBuildType): Array<String> { ...@@ -111,8 +111,7 @@ fun skiaPreprocessorFlags(os: OS, buildType: SkiaBuildType): Array<String> {
fun Project.configureSignAndPublishDependencies() { fun Project.configureSignAndPublishDependencies() {
if (supportWasm) { if (supportWasm) {
tasks.forEach { task -> tasks.configureEach {
val name = task.name
val publishJs = "publishJsPublicationTo" val publishJs = "publishJsPublicationTo"
val publishWasm = "publishSkikoWasmRuntimePublicationTo" val publishWasm = "publishSkikoWasmRuntimePublicationTo"
val publishWasmPub = "publishWasmJsPublicationTo" val publishWasmPub = "publishWasmJsPublicationTo"
...@@ -121,16 +120,15 @@ fun Project.configureSignAndPublishDependencies() { ...@@ -121,16 +120,15 @@ fun Project.configureSignAndPublishDependencies() {
val signWasmPub = "signWasmJsPublication" val signWasmPub = "signWasmJsPublication"
when { when {
name.startsWith(publishJs) -> task.dependsOn(signWasm, signWasmPub) name.startsWith(publishJs) -> dependsOn(signWasm, signWasmPub)
name.startsWith(publishWasm) -> task.dependsOn(signJs) name.startsWith(publishWasm) -> dependsOn(signJs)
name.startsWith(publishWasmPub) -> task.dependsOn(signJs) name.startsWith(publishWasmPub) -> dependsOn(signJs)
name.startsWith(signWasmPub) -> task.dependsOn(signWasm) name.startsWith(signWasmPub) -> dependsOn(signWasm)
} }
} }
} }
if (supportAndroid) { if (supportAndroid) {
tasks.forEach { task -> tasks.configureEach {
val name = task.name
val signAndroid = "signAndroidPublication" val signAndroid = "signAndroidPublication"
val generateMetadata = "generateMetadataFileForAndroidPublication" val generateMetadata = "generateMetadataFileForAndroidPublication"
val publishAndroid = "publishAndroidPublicationTo" val publishAndroid = "publishAndroidPublicationTo"
...@@ -142,16 +140,16 @@ fun Project.configureSignAndPublishDependencies() { ...@@ -142,16 +140,16 @@ fun Project.configureSignAndPublishDependencies() {
when { when {
name.startsWith(signAndroid) || name.startsWith(generateMetadata) -> { name.startsWith(signAndroid) || name.startsWith(generateMetadata) -> {
task.dependsOn(skikoAndroidJar) dependsOn(skikoAndroidJar)
} }
name.startsWith(publishAndroid) -> { name.startsWith(publishAndroid) -> {
task.dependsOn(signX64, signArm64) dependsOn(signX64, signArm64)
} }
name.startsWith(publishX64) -> { name.startsWith(publishX64) -> {
task.dependsOn(signAndroid, signArm64) dependsOn(signAndroid, signArm64)
} }
name.startsWith(publishArm64) -> { name.startsWith(publishArm64) -> {
task.dependsOn(signX64, signAndroid) dependsOn(signX64, signAndroid)
} }
} }
} }
...@@ -161,7 +159,8 @@ fun Project.configureSignAndPublishDependencies() { ...@@ -161,7 +159,8 @@ fun Project.configureSignAndPublishDependencies() {
fun KotlinTarget.generateVersion( fun KotlinTarget.generateVersion(
targetOs: OS, targetOs: OS,
targetArch: Arch, targetArch: Arch,
skikoProperties: SkikoProperties skikoProperties: SkikoProperties,
compilationName: String = "main"
) { ) {
val targetName = this.name val targetName = this.name
val isUikitSim = isUikitSimulator() val isUikitSim = isUikitSimulator()
...@@ -194,9 +193,11 @@ fun KotlinTarget.generateVersion( ...@@ -194,9 +193,11 @@ fun KotlinTarget.generateVersion(
} }
} }
val compilation = compilations["main"] ?: error("Could not find 'main' compilation for target '$this'") // Needs to be lazily loaded as android compilations are not available right away
compilation.compileKotlinTaskProvider.configure { compilations.matching { it.name == compilationName }.configureEach {
dependsOn(generateVersionTask) compileTaskProvider.configure {
(this as KotlinCompileTool).source(generatedDir.get().asFile) dependsOn(generateVersionTask)
(this as KotlinCompileTool).source(generatedDir.get().asFile)
}
} }
} }
\ No newline at end of file
...@@ -515,8 +515,13 @@ fun SkikoProjectContext.setupJvmTestTask(skikoAwtJarForTests: TaskProvider<Jar>, ...@@ -515,8 +515,13 @@ fun SkikoProjectContext.setupJvmTestTask(skikoAwtJarForTests: TaskProvider<Jar>,
} }
fun Project.androidHomePath(): Provider<String> { fun Project.androidHomePath(): Provider<String> {
val androidHomeFromSdkRoot: Provider<String> = val androidHomeFromSdkHome: Provider<String> =
project.providers.environmentVariable("ANDROID_HOME")
// ANDROID_SDK_ROOT name is deprecated in favor of ANDROID_HOME
val deprecatedAndroidHomeFromSdkRoot: Provider<String> =
project.providers.environmentVariable("ANDROID_SDK_ROOT") project.providers.environmentVariable("ANDROID_SDK_ROOT")
val androidHomeFromUserHome: Provider<String> = val androidHomeFromUserHome: Provider<String> =
project.providers.systemProperty("user.home") project.providers.systemProperty("user.home")
.map { userHome -> .map { userHome ->
...@@ -525,26 +530,7 @@ fun Project.androidHomePath(): Provider<String> { ...@@ -525,26 +530,7 @@ fun Project.androidHomePath(): Provider<String> {
.firstOrNull { File(it).exists() } .firstOrNull { File(it).exists() }
?: error("Define Android SDK via ANDROID_SDK_ROOT") ?: error("Define Android SDK via ANDROID_SDK_ROOT")
} }
return androidHomeFromSdkRoot return androidHomeFromSdkHome
.orElse(deprecatedAndroidHomeFromSdkRoot)
.orElse(androidHomeFromUserHome) .orElse(androidHomeFromUserHome)
} }
fun Project.androidJar(askedVersion: String = ""): Provider<File> =
androidHomePath().map { androidHomePath ->
val androidHome = File(androidHomePath)
val version = if (askedVersion.isEmpty()) {
val platformsDir = androidHome.resolve("platforms")
val versions = platformsDir.list().orEmpty()
versions.maxByOrNull { name -> // possible name: "android-32", "android-33-ext4"
name.split("-").getOrNull(1)?.toIntOrNull() ?: 0
} ?: error(
buildString {
appendLine("'$platformsDir' does not contain any directories matching expected 'android-NUMBER' format: ${versions}")
}
)
} else {
"android-$askedVersion"
}
androidHome.resolve("platforms/$version/android.jar").also {
println("Skiko task androidJar uses android SDK in $it")
}
}
\ No newline at end of file
...@@ -2,20 +2,28 @@ pluginManagement { ...@@ -2,20 +2,28 @@ pluginManagement {
repositories { repositories {
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
google()
} }
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/internal") maven("https://maven.pkg.jetbrains.space/public/p/compose/internal")
maven("https://maven.pkg.jetbrains.space/public/p/space/maven") maven("https://maven.pkg.jetbrains.space/public/p/space/maven")
google()
} }
dependencies { dependencies {
// TODO Removing this makes publishing module below crash android internal plugin
classpath("org.ow2.asm:asm:9.6")
// TODO https://youtrack.jetbrains.com/issue/SKIKO-1003/Unify-Maven-publication-of-Skiko-with-Compose // TODO https://youtrack.jetbrains.com/issue/SKIKO-1003/Unify-Maven-publication-of-Skiko-with-Compose
classpath("org.jetbrains.compose.internal.build-helpers:publishing:0.1.3") classpath("org.jetbrains.compose.internal.build-helpers:publishing:0.1.3")
// used by org.jetbrains.compose.internal.build-helpers:publishing because of https://youtrack.jetbrains.com/issue/CMP-7603/Fix-Maven-Central-publication // used by org.jetbrains.compose.internal.build-helpers:publishing because of https://youtrack.jetbrains.com/issue/CMP-7603/Fix-Maven-Central-publication
classpath("org.jetbrains:space-sdk-jvm:2024.3-185883") classpath("org.jetbrains:space-sdk-jvm:2024.3-185883")
classpath("org.kohsuke:github-api:1.116") classpath("org.kohsuke:github-api:1.116")
// Added dependency for Android Gradle plugin
classpath("com.android.tools.build:gradle:7.4.2")
} }
} }
...@@ -23,6 +31,7 @@ pluginManagement { ...@@ -23,6 +31,7 @@ pluginManagement {
val kotlinVersion = extra["kotlin.version"] as String val kotlinVersion = extra["kotlin.version"] as String
kotlin("jvm").version(kotlinVersion) kotlin("jvm").version(kotlinVersion)
kotlin("multiplatform").version(kotlinVersion) kotlin("multiplatform").version(kotlinVersion)
id("com.android.library").version("7.4.2") apply false
} }
} }
rootProject.name = "skiko" rootProject.name = "skiko"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment