Unverified Commit 9e1a2c85 authored by Nikolay Igotti's avatar Nikolay Igotti Committed by GitHub

Native build on Linux (#243)

parent dc43f792
...@@ -58,7 +58,7 @@ jobs: ...@@ -58,7 +58,7 @@ jobs:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9
sudo update-alternatives --config gcc sudo update-alternatives --config gcc
sudo apt-get install ninja-build fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev zip -y sudo apt-get install ninja-build fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev zip -y
./gradlew -i jvmTest ./gradlew -Pskiko.native.enabled=true -i linuxX64Test jvmTest
./gradlew publishToMavenLocal ./gradlew publishToMavenLocal
js: js:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
......
...@@ -59,6 +59,7 @@ val crossTargets = listOf( ...@@ -59,6 +59,7 @@ val crossTargets = listOf(
OS.IOS to Arch.Arm64, OS.IOS to Arch.Arm64,
OS.MacOS to Arch.X64, OS.MacOS to Arch.X64,
OS.MacOS to Arch.Arm64, OS.MacOS to Arch.Arm64,
OS.Linux to Arch.X64
) )
class NativeCompilationInfo(val target: org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget) { class NativeCompilationInfo(val target: org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget) {
...@@ -127,8 +128,7 @@ val wasmCrossCompile = tasks.register<CrossCompileTask>("wasmCrossCompile") { ...@@ -127,8 +128,7 @@ val wasmCrossCompile = tasks.register<CrossCompileTask>("wasmCrossCompile") {
includeHeadersNonRecursive(skiaHeadersDirs(unpackedSkia)) includeHeadersNonRecursive(skiaHeadersDirs(unpackedSkia))
flags.set(listOf( flags.set(listOf(
*skiaPreprocessorFlags(), *skiaPreprocessorFlags()
"-DSK_SUPPORT_GPU=1"
)) ))
} }
...@@ -149,8 +149,7 @@ fun registerNativeBridgesTask(os: OS, arch: Arch): TaskProvider<CrossCompileTask ...@@ -149,8 +149,7 @@ fun registerNativeBridgesTask(os: OS, arch: Arch): TaskProvider<CrossCompileTask
"-stdlib=libc++", "-stdlib=libc++",
"-DSK_SHAPER_CORETEXT_AVAILABLE", "-DSK_SHAPER_CORETEXT_AVAILABLE",
"-DSK_BUILD_FOR_IOS", "-DSK_BUILD_FOR_IOS",
"-DSK_METAL", "-DSK_METAL"
"-DSK_SUPPORT_GPU=1"
) )
when (arch) { when (arch) {
Arch.Arm64 -> Arch.Arm64 ->
...@@ -178,10 +177,22 @@ fun registerNativeBridgesTask(os: OS, arch: Arch): TaskProvider<CrossCompileTask ...@@ -178,10 +177,22 @@ fun registerNativeBridgesTask(os: OS, arch: Arch): TaskProvider<CrossCompileTask
"-DSK_SHAPER_CORETEXT_AVAILABLE", "-DSK_SHAPER_CORETEXT_AVAILABLE",
"-DSK_BUILD_FOR_MAC", "-DSK_BUILD_FOR_MAC",
"-DSK_METAL", "-DSK_METAL",
"-DSK_SUPPORT_GPU=1",
*skiaPreprocessorFlags() *skiaPreprocessorFlags()
)) ))
} }
OS.Linux -> {
flags.set(listOf(
"-std=c++17",
"-fno-rtti",
"-fno-exceptions",
"-fvisibility=hidden",
"-fvisibility-inlines-hidden",
"-DSK_BUILD_FOR_LINUX",
"-D_GLIBCXX_USE_CXX11_ABI=0",
*skiaPreprocessorFlags()
))
}
else -> throw GradleException("$os not yet supported")
} }
crossCompileTargetOS.set(osArch.first) crossCompileTargetOS.set(osArch.first)
...@@ -291,6 +302,7 @@ kotlin { ...@@ -291,6 +302,7 @@ kotlin {
when ("${hostOs.id}-${hostArch.id}") { when ("${hostOs.id}-${hostArch.id}") {
"macos-x64" -> allNativeTargets[OS.MacOS to Arch.X64] = NativeCompilationInfo(macosX64()) "macos-x64" -> allNativeTargets[OS.MacOS to Arch.X64] = NativeCompilationInfo(macosX64())
"macos-arm64" -> allNativeTargets[OS.MacOS to Arch.Arm64] = NativeCompilationInfo(macosArm64()) "macos-arm64" -> allNativeTargets[OS.MacOS to Arch.Arm64] = NativeCompilationInfo(macosArm64())
"linux-x64" -> allNativeTargets[OS.Linux to Arch.X64] = NativeCompilationInfo(linuxX64())
} }
if (hostOs == OS.MacOS) { if (hostOs == OS.MacOS) {
...@@ -301,7 +313,8 @@ kotlin { ...@@ -301,7 +313,8 @@ kotlin {
for ((osArch, compilation) in allNativeTargets) { for ((osArch, compilation) in allNativeTargets) {
val targetString = "${osArch.first.id}-${osArch.second.id}" val targetString = "${osArch.first.id}-${osArch.second.id}"
val unzipper = skiaDirProviderForCrossTargets[osArch]!! val unzipper = skiaDirProviderForCrossTargets[osArch] ?:
throw GradleException("add $osArch to the list of cross-targets")
val unpackedSkia = unzipper.get() val unpackedSkia = unzipper.get()
val skiaDir = unpackedSkia.absolutePath val skiaDir = unpackedSkia.absolutePath
...@@ -309,12 +322,22 @@ kotlin { ...@@ -309,12 +322,22 @@ kotlin {
val allLibraries = skiaStaticLibraries(skiaDir, targetString) + bridgesLibrary val allLibraries = skiaStaticLibraries(skiaDir, targetString) + bridgesLibrary
compilation.target.compilations.all { compilation.target.compilations.all {
val skiaBinDir = "$skiaDir/out/${buildType.id}-${osArch.first.id}-${osArch.second.id}"
kotlinOptions { kotlinOptions {
val linkerFlags = when (osArch.first) { val linkerFlags = when (osArch.first) {
OS.MacOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal") OS.MacOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal")
OS.IOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal", OS.IOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics", "-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText") "-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() else -> emptyList()
} }
freeCompilerArgs = allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags freeCompilerArgs = allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags
...@@ -335,6 +358,15 @@ kotlin { ...@@ -335,6 +358,15 @@ kotlin {
val outDir = "$buildDir/nativeBridges/static/$targetString" val outDir = "$buildDir/nativeBridges/static/$targetString"
val staticLib = "$outDir/skiko-native-bridges-$targetString.a" val staticLib = "$outDir/skiko-native-bridges-$targetString.a"
workingDir = File(outDir) workingDir = File(outDir)
if (osArch.first == OS.Linux) {
executable = "ar"
argumentProviders.add {
listOf(
"-crs",
staticLib
)
}
} else {
executable = "libtool" executable = "libtool"
argumentProviders.add { argumentProviders.add {
listOf( listOf(
...@@ -343,6 +375,7 @@ kotlin { ...@@ -343,6 +375,7 @@ kotlin {
staticLib staticLib
) )
} }
}
argumentProviders.add { objectFiles.files.map { it.absolutePath } } argumentProviders.add { objectFiles.files.map { it.absolutePath } }
file(outDir).mkdirs() file(outDir).mkdirs()
outputs.dir(outDir) outputs.dir(outDir)
...@@ -396,6 +429,20 @@ kotlin { ...@@ -396,6 +429,20 @@ kotlin {
val nativeTest by creating { val nativeTest by creating {
dependsOn(commonTest) dependsOn(commonTest)
} }
if (hostOs == OS.Linux) {
val linuxMain by creating {
dependsOn(nativeMain)
}
val linuxTest by creating {
dependsOn(nativeTest)
}
val linuxX64Main by getting {
dependsOn(linuxMain)
}
val linuxX64Test by getting {
dependsOn(linuxTest)
}
}
if (hostOs == OS.MacOS) { if (hostOs == OS.MacOS) {
val macosMain by creating { val macosMain by creating {
dependsOn(nativeMain) dependsOn(nativeMain)
......
...@@ -20,9 +20,9 @@ enum class Arch( ...@@ -20,9 +20,9 @@ enum class Arch(
val id: String, val id: String,
val clangFlags: Array<String> val clangFlags: Array<String>
) { ) {
X64("x64", arrayOf("-arch", "x86_64")), X64("x64", arrayOf()),
Arm64("arm64", arrayOf("-arch", "arm64")), Arm64("arm64", arrayOf()),
Wasm("wasm", arrayOf("-std=c++17", "--bind", "-DSKIKO_WASM")) Wasm("wasm", arrayOf("--bind", "-DSKIKO_WASM"))
} }
enum class SkiaBuildType( enum class SkiaBuildType(
...@@ -31,8 +31,8 @@ enum class SkiaBuildType( ...@@ -31,8 +31,8 @@ enum class SkiaBuildType(
val clangFlags: Array<String>, val clangFlags: Array<String>,
val msvcFlags: Array<String> val msvcFlags: Array<String>
) { ) {
DEBUG("Debug", arrayOf("-DSK_DEBUG"), arrayOf("-std=c++14", "-g"), emptyArray()), DEBUG("Debug", arrayOf("-DSK_DEBUG"), arrayOf("-std=c++17", "-g"), emptyArray()),
RELEASE("Release", arrayOf("-DNDEBUG"), arrayOf("-std=c++14", "-O3"), arrayOf("/O2")) RELEASE("Release", arrayOf("-DNDEBUG"), arrayOf("-std=c++17", "-O3"), arrayOf("/O2"))
; ;
override fun toString() = id override fun toString() = id
} }
......
...@@ -20,3 +20,12 @@ SKIKO_EXPORT KInt org_jetbrains_skia_impl_RefCnt__getRefCount(KNativePointer ptr ...@@ -20,3 +20,12 @@ SKIKO_EXPORT KInt org_jetbrains_skia_impl_RefCnt__getRefCount(KNativePointer ptr
SkRefCnt* instance = reinterpret_cast<SkRefCnt*>(ptr); SkRefCnt* instance = reinterpret_cast<SkRefCnt*>(ptr);
return reinterpret_cast<SkRefCntHack*>(instance)->fRefCnt.load(std::memory_order_relaxed); return reinterpret_cast<SkRefCntHack*>(instance)->fRefCnt.load(std::memory_order_relaxed);
} }
#ifdef SK_BUILD_FOR_LINUX
// TODO: fix properly, now just stub this incompatible symbol.
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88782
// We likely shall switch to more recent Skia build, i.e. ubuntu18 variant.
extern "C" void _ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info() {
TODO("_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info called!");
}
#endif
\ No newline at end of file
package org.jetbrains.skiko.native.context
import org.jetbrains.skia.*
import org.jetbrains.skiko.native.*
internal actual fun createContextHandler(layer: HardwareLayer): ContextHandler {
TODO()
}
package org.jetbrains.skiko.native
actual abstract class HardwareLayer
\ No newline at end of file
package org.jetbrains.skiko.native
import org.jetbrains.skiko.GraphicsApi
import org.jetbrains.skiko.redrawer.Redrawer
import org.jetbrains.skiko.native.redrawer.LinuxOpenGLRedrawer
internal actual fun makePlatformOperations(): PlatformOperations {
return object: PlatformOperations {
override fun createRedrawer(layer: HardwareLayer, properties: SkiaLayerProperties): Redrawer =
when (SkikoProperties.renderApi) {
GraphicsApi.OPENGL -> LinuxOpenGLRedrawer(layer, properties)
else -> error("No other renderings for native yet")
}
}
}
\ No newline at end of file
package org.jetbrains.skiko.native.redrawer
import org.jetbrains.skiko.native.*
import org.jetbrains.skiko.redrawer.Redrawer
internal class LinuxOpenGLRedrawer(
private val layer: HardwareLayer,
private val properties: SkiaLayerProperties
) : Redrawer {
override fun dispose() {
TODO()
}
override fun syncSize() {
TODO()
}
override fun needRedraw() {
TODO()
}
override fun redrawImmediately() {
TODO()
}
}
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