Unverified Commit 83a746d4 authored by Alexey Tsvetkov's avatar Alexey Tsvetkov Committed by GitHub

Allow configuring all targets for publishing (#380)

* Allow to configure all targets for publishing

* Update emscripten dockerfile

* Print PATH in error message
parent c20bf0c5
...@@ -3,6 +3,7 @@ import org.gradle.crypto.checksum.Checksum ...@@ -3,6 +3,7 @@ import org.gradle.crypto.checksum.Checksum
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import org.jetbrains.compose.internal.publishing.MavenCentralProperties import org.jetbrains.compose.internal.publishing.MavenCentralProperties
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins { plugins {
kotlin("multiplatform") version "1.5.31" kotlin("multiplatform") version "1.5.31"
...@@ -44,21 +45,6 @@ val windowsSdkPaths: WindowsSdkPaths by lazy { ...@@ -44,21 +45,6 @@ val windowsSdkPaths: WindowsSdkPaths by lazy {
findWindowsSdkPathsForCurrentOS(gradle) findWindowsSdkPathsForCurrentOS(gradle)
} }
val crossTargets = listOf(
OS.Wasm to Arch.Wasm,
OS.IOS to Arch.X64,
OS.IOS to Arch.Arm64,
OS.MacOS to Arch.X64,
OS.MacOS to Arch.Arm64,
OS.Linux to Arch.X64
)
class NativeCompilationInfo(val target: org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget) {
var linkTask: Provider<Exec>? = null
}
val allNativeTargets = mutableMapOf<Pair<OS, Arch>, NativeCompilationInfo>()
val skiaWasmDir = registerOrGetSkiaDirProvider(OS.Wasm, Arch.Wasm) val skiaWasmDir = registerOrGetSkiaDirProvider(OS.Wasm, Arch.Wasm)
val compileWasm = tasks.register<CompileSkikoCppTask>("compileWasm") { val compileWasm = tasks.register<CompileSkikoCppTask>("compileWasm") {
...@@ -87,7 +73,7 @@ val compileWasm = tasks.register<CompileSkikoCppTask>("compileWasm") { ...@@ -87,7 +73,7 @@ val compileWasm = tasks.register<CompileSkikoCppTask>("compileWasm") {
)) ))
} }
fun registerNativeBridgesTask(os: OS, arch: Arch): TaskProvider<CompileSkikoCppTask> { fun compileNativeBridgesTask(os: OS, arch: Arch): TaskProvider<CompileSkikoCppTask> {
val skiaNativeDir = registerOrGetSkiaDirProvider(os, arch) val skiaNativeDir = registerOrGetSkiaDirProvider(os, arch)
return tasks.register<CompileSkikoCppTask>("${os.id}_${arch.id}_CrossCompile") { return tasks.register<CompileSkikoCppTask>("${os.id}_${arch.id}_CrossCompile") {
...@@ -241,91 +227,11 @@ kotlin { ...@@ -241,91 +227,11 @@ kotlin {
} }
if (supportNative) { if (supportNative) {
when ("${hostOs.id}-${hostArch.id}") { configureNativeTarget(OS.MacOS, Arch.X64, macosX64())
"macos-x64" -> allNativeTargets[OS.MacOS to Arch.X64] = NativeCompilationInfo(macosX64()) configureNativeTarget(OS.MacOS, Arch.Arm64, macosArm64())
"macos-arm64" -> allNativeTargets[OS.MacOS to Arch.Arm64] = NativeCompilationInfo(macosArm64()) configureNativeTarget(OS.Linux, Arch.X64, linuxX64())
"linux-x64" -> allNativeTargets[OS.Linux to Arch.X64] = NativeCompilationInfo(linuxX64()) configureNativeTarget(OS.IOS, Arch.Arm64, iosArm64())
} configureNativeTarget(OS.IOS, Arch.X64, iosX64())
if (hostOs == OS.MacOS) {
allNativeTargets[OS.IOS to Arch.Arm64] = NativeCompilationInfo(iosArm64())
allNativeTargets[OS.IOS to Arch.X64] = NativeCompilationInfo(iosX64())
}
for ((osArch, compilation) in allNativeTargets) {
val targetString = "${osArch.first.id}-${osArch.second.id}"
val unzipper = registerOrGetSkiaDirProvider(osArch.first, osArch.second)
val unpackedSkia = unzipper.get()
val skiaDir = unpackedSkia.absolutePath
val bridgesLibrary = "$buildDir/nativeBridges/static/$targetString/skiko-native-bridges-$targetString.a"
val allLibraries = skiaStaticLibraries(skiaDir, targetString) + bridgesLibrary
compilation.target.compilations.all {
val skiaBinDir = "$skiaDir/out/${buildType.id}-${osArch.first.id}-${osArch.second.id}"
kotlinOptions {
val linkerFlags = when (osArch.first) {
OS.MacOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText",
"-linker-option", "-framework", "-linker-option", "CoreServices"
)
OS.IOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText")
OS.Linux -> listOf(
"-linker-option", "-L/usr/lib/x86_64-linux-gnu",
"-linker-option", "-lfontconfig",
"-linker-option", "-lGL",
// TODO: an ugly hack, Linux linker searches only unresolved symbols.
"-linker-option", "$skiaBinDir/libskshaper.a",
"-linker-option", "$skiaBinDir/libskunicode.a",
"-linker-option", "$skiaBinDir/libskia.a"
)
else -> emptyList()
}
freeCompilerArgs = allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags
}
}
val crossCompileTask = registerNativeBridgesTask(osArch.first, osArch.second)
val info = allNativeTargets[osArch]!!
info.linkTask = project.tasks.register<Exec>("linkNativeBridges$targetString") {
dependsOn(crossCompileTask)
val objectFilesDir = crossCompileTask.map { it.outDir.get() }
val objectFiles = project.fileTree(objectFilesDir) {
include("**/*.o")
}
inputs.files(objectFiles)
val outDir = "$buildDir/nativeBridges/static/$targetString"
val staticLib = "$outDir/skiko-native-bridges-$targetString.a"
workingDir = File(outDir)
if (osArch.first == OS.Linux) {
executable = "ar"
argumentProviders.add {
listOf(
"-crs",
staticLib
)
}
} else {
executable = "libtool"
argumentProviders.add {
listOf(
"-static",
"-o",
staticLib
)
}
}
argumentProviders.add { objectFiles.files.map { it.absolutePath } }
file(outDir).mkdirs()
outputs.dir(outDir)
}
}
} }
sourceSets { sourceSets {
...@@ -388,78 +294,130 @@ kotlin { ...@@ -388,78 +294,130 @@ kotlin {
val nativeTest by creating { val nativeTest by creating {
dependsOn(nativeJsTest) dependsOn(nativeJsTest)
} }
if (hostOs == OS.Linux) { val linuxMain by creating {
val linuxMain by creating { dependsOn(nativeMain)
dependsOn(nativeMain)
}
val linuxTest by creating {
dependsOn(nativeTest)
}
when (targetArch) {
Arch.X64 -> {
val linuxX64Main by getting {
dependsOn(linuxMain)
}
val linuxX64Test by getting {
dependsOn(linuxTest)
}
}
}
} }
if (hostOs == OS.MacOS) { val linuxTest by creating {
val darwinMain by creating { dependsOn(nativeTest)
dependsOn(nativeMain) }
} val linuxX64Main by getting {
val darwinTest by creating { dependsOn(linuxMain)
dependsOn(nativeTest) }
} val linuxX64Test by getting {
val macosMain by creating { dependsOn(linuxTest)
dependsOn(darwinMain)
}
val macosTest by creating {
dependsOn(darwinTest)
}
val iosMain by creating {
dependsOn(darwinMain)
}
val iosTest by creating {
dependsOn(darwinTest)
}
val macosArch = when (targetArch) {
Arch.X64 -> {
val macosX64Main by getting {
dependsOn(macosMain)
}
val macosX64Test by getting {
dependsOn(macosTest)
}
macosX64Main to macosX64Test
}
Arch.Arm64 -> {
val macosArm64Main by getting {
dependsOn(macosMain)
}
val macosArm64Test by getting {
dependsOn(macosTest)
}
macosArm64Main to macosArm64Test
}
else -> throw GradleException("Unsupported arch $targetArch for macOS")
}
val iosX64Main by getting {
dependsOn(iosMain)
}
val iosX64Test by getting {
dependsOn(iosTest)
}
val iosArm64Main by getting {
dependsOn(iosMain)
}
val iosArm64Test by getting {
dependsOn(iosTest)
}
} }
val darwinMain by creating {
dependsOn(nativeMain)
}
val darwinTest by creating {
dependsOn(nativeTest)
}
val macosMain by creating {
dependsOn(darwinMain)
}
val macosTest by creating {
dependsOn(darwinTest)
}
val iosMain by creating {
dependsOn(darwinMain)
}
val iosTest by creating {
dependsOn(darwinTest)
}
val macosX64Main by getting {
dependsOn(macosMain)
}
val macosX64Test by getting {
dependsOn(macosTest)
}
val macosArm64Main by getting {
dependsOn(macosMain)
}
val macosArm64Test by getting {
dependsOn(macosTest)
}
val iosX64Main by getting {
dependsOn(iosMain)
}
val iosX64Test by getting {
dependsOn(iosTest)
}
val iosArm64Main by getting {
dependsOn(iosMain)
}
val iosArm64Test by getting {
dependsOn(iosTest)
}
}
}
}
fun configureNativeTarget(os: OS, arch: Arch, target: KotlinNativeTarget) {
val targetString = "${os.id}-${arch.id}"
val unzipper = registerOrGetSkiaDirProvider(os, arch)
val unpackedSkia = unzipper.get()
val skiaDir = unpackedSkia.absolutePath
val bridgesLibrary = "$buildDir/nativeBridges/static/$targetString/skiko-native-bridges-$targetString.a"
val allLibraries = skiaStaticLibraries(skiaDir, targetString) + bridgesLibrary
target.compilations.all {
val skiaBinDir = "$skiaDir/out/${buildType.id}-$targetString"
kotlinOptions {
val linkerFlags = when (os) {
OS.MacOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText",
"-linker-option", "-framework", "-linker-option", "CoreServices"
)
OS.IOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText")
OS.Linux -> listOf(
"-linker-option", "-L/usr/lib/x86_64-linux-gnu",
"-linker-option", "-lfontconfig",
"-linker-option", "-lGL",
// TODO: an ugly hack, Linux linker searches only unresolved symbols.
"-linker-option", "$skiaBinDir/libskshaper.a",
"-linker-option", "$skiaBinDir/libskunicode.a",
"-linker-option", "$skiaBinDir/libskia.a"
)
else -> emptyList()
}
freeCompilerArgs = allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags
}
}
val crossCompileTask = compileNativeBridgesTask(os, arch)
val linkTask = project.tasks.register<Exec>("linkNativeBridges$targetString") {
dependsOn(crossCompileTask)
val objectFilesDir = crossCompileTask.map { it.outDir.get() }
val objectFiles = project.fileTree(objectFilesDir) {
include("**/*.o")
}
inputs.files(objectFiles)
val outDir = "$buildDir/nativeBridges/static/$targetString"
val staticLib = "$outDir/skiko-native-bridges-$targetString.a"
workingDir = File(outDir)
when (os) {
OS.Linux -> {
executable = "ar"
argumentProviders.add { listOf("-crs", staticLib) }
}
OS.MacOS, OS.IOS -> {
executable = "libtool"
argumentProviders.add { listOf("-static", "-o", staticLib) }
}
else -> error("Unexpected OS for native bridges linking: $os")
} }
argumentProviders.add { objectFiles.files.map { it.absolutePath } }
file(outDir).mkdirs()
outputs.dir(outDir)
}
target.compilations.all {
compileKotlinTask.dependsOn(linkTask)
} }
} }
...@@ -652,7 +610,7 @@ val linkJvmBindings = tasks.register<LinkSkikoTask>("linkJvmBindings") { ...@@ -652,7 +610,7 @@ val linkJvmBindings = tasks.register<LinkSkikoTask>("linkJvmBindings") {
when (targetOs) { when (targetOs) {
OS.MacOS -> { OS.MacOS -> {
dependsOn(project.tasks.named("objcCompile")) dependsOn("objcCompile")
objectFiles += fileTree("$buildDir/objc/$target") { objectFiles += fileTree("$buildDir/objc/$target") {
include("**/*.o") include("**/*.o")
} }
...@@ -797,7 +755,6 @@ fun sealBinary(sealer: String, lib: File) { ...@@ -797,7 +755,6 @@ fun sealBinary(sealer: String, lib: File) {
println("Sealed!") println("Sealed!")
} }
fun remoteSignCurl(signHost: String, lib: File, out: File) { fun remoteSignCurl(signHost: String, lib: File, out: File) {
println("Remote signing $lib on $signHost") println("Remote signing $lib on $signHost")
val user = skiko.signUser ?: error("signUser is null") val user = skiko.signUser ?: error("signUser is null")
...@@ -1013,8 +970,6 @@ val emptyJavadocJar by tasks.registering(Jar::class) { ...@@ -1013,8 +970,6 @@ val emptyJavadocJar by tasks.registering(Jar::class) {
archiveClassifier.set("javadoc") archiveClassifier.set("javadoc")
} }
publishing { publishing {
repositories { repositories {
configureEach { configureEach {
...@@ -1133,12 +1088,6 @@ afterEvaluate { ...@@ -1133,12 +1088,6 @@ afterEvaluate {
tasks.withType<KotlinNativeCompile>().configureEach { tasks.withType<KotlinNativeCompile>().configureEach {
dependsOn(generateVersion) dependsOn(generateVersion)
source(generatedKotlin) source(generatedKotlin)
// TDOD: do we need this 'if'?
if (supportNative) {
val compilationInfoKey = allNativeTargets.keys.singleOrNull { "${it.first.id}_${it.second.id}" == this.target }
?: throw GradleException("No cross-target for ${this.target}")
dependsOn(allNativeTargets[compilationInfoKey]!!.linkTask)
}
} }
} }
......
...@@ -180,7 +180,7 @@ abstract class CompileSkikoCppTask : AbstractSkikoNativeToolTask() { ...@@ -180,7 +180,7 @@ abstract class CompileSkikoCppTask : AbstractSkikoNativeToolTask() {
if (file.isFile) return file if (file.isFile) return file
} }
error("Could not find compiler '$compilerNameOrFile' in PATH") error("Could not find compiler '$compilerNameOrFile' in PATH: $paths")
} }
override fun cleanStaleOutput(mode: ToolMode.NonIncremental) { override fun cleanStaleOutput(mode: ToolMode.NonIncremental) {
......
...@@ -6,11 +6,11 @@ RUN apt-get update -y && \ ...@@ -6,11 +6,11 @@ RUN apt-get update -y && \
apt-get install git curl wget -y && \ apt-get install git curl wget -y && \
apt-get install python -y && \ apt-get install python -y && \
apt-get install openjdk-11-jdk -y apt-get install openjdk-11-jdk -y
RUN export EMSDK_DIR=/usr/emsdk && \ ENV EMSDK_DIR=/usr/emsdk
export EMSDK_VER=2.0.29 && \ ENV EMSDK_VER=2.0.29
git clone https://github.com/emscripten-core/emsdk.git $EMSDK_DIR && \ RUN git clone https://github.com/emscripten-core/emsdk.git $EMSDK_DIR && \
$EMSDK_DIR/emsdk install $EMSDK_VER && \ $EMSDK_DIR/emsdk install $EMSDK_VER && \
$EMSDK_DIR/emsdk activate $EMSDK_VER && \ $EMSDK_DIR/emsdk activate $EMSDK_VER
echo "source $EMSDK_DIR/emsdk_env.sh" >> ~/.bashrc ENV PATH=$EMSDK_DIR/upstream/emscripten:$PATH
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF
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