GTK3 Kotlin/Native Sample

This is a working example of how to write and build a GTK3 application in Kotlin/Native. It includes a Flatpak manifest that successfully builds the application against the elementary Flatpak runtime.

The GTK-KT library is used to wrap GTK in a nice Kotlin-like API. If you wish to build this project locally, you will first need to build and install GTK-KT to your local Maven repository as per the instructions in its README.

Most of the files here are the standard Kotlin/Native template files as produced by IntelliJ IDEA. The following customizations have been made:

maven-modules.json

This is generated by flatpak-maven-generator with the following command:

flatpak-maven-generator -r https://plugins.gradle.org/m2/ org.jetbrains.kotlin.multiplatform:org.jetbrains.kotlin.multiplatform.gradle.plugin:1.5.0 org.jetbrains.kotlin:kotlin-stdlib:1.5.21 org.jetbrains.kotlin:kotlin-reflect:1.5.21 org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-native-mt org.jetbrains.kotlinx:kotlinx-coroutines-core-linuxx64:1.5.0-native-mt org.jetbrains.kotlinx:atomicfu:0.16.1

This JSON file instructs flatpak-builder to download the requested Maven artifacts (and their recursive dependencies) into a local Maven repository. As the flatpak-builder sandbox does not allow internet access, the Gradle build scripts cannot download dependencies, so we have to pre-provide them in this way.

build.gradle.kts

The following section was added to the standard IDEA template:

repositories {
    mavenCentral()
    mavenLocal()
    maven() { url = uri("/app/maven-local") }
}

This allows the build to work locally (outside the Flatpak sandbox), by using mavenLocal for GTK-KT and mavenCentral on the internet for other dependencies. The /app/maven-local line allows the build inside the sandbox to find dependencies by using the mirrored maven repository created by the JSON file above.

settings.gradle.kts

The following section was added to the standard IDEA template:

pluginManagement {
    repositories {
        maven(url = "/app/maven-local")
        gradlePluginPortal()
    }
}

Again, this allows Gradle to find plugins in the local Maven repository inside the sandbox, this wouldn’t be necessary if not building as a Flatpak.

local-maven-repository.patch

This is a patch applied to gtk-kt during a Flatpak build to allow it to find its Maven artifacts.

io.github.davidmhewitt.KotlinSample.yml

This is the Flatpak build manifest. In order:

  • The kotlin-native module downloads and unpacks the Kotlin Native compiler to /app/kotlin-native. This is entirely cleaned up after the build has finished to make the resulting Flatpak as small as possible.
  • The konan-deps module downloads dependencies of the Kotlin compiler. This is essentially a full GCC/Clang/LLVM toolchain. This is fairly inefficient use of bandwidth during the build as these tools could be available in the Flatpak SDK, but it seems Kotlin does not fully support using the host’s toolchain yet. This is entirely cleaned up after the build.
  • The maven-modules module downloads a local mirror of the artifacts required from Maven repos to /app/maven-local as specified in the JSON file. This repository is cleaned up after the build.
  • The gtk-kt module clones and builds gtk-kt and publishes it to the /app/maven-local repository. We’re selective about which subprojects we build to save time. This is cleaned up after the build.
  • Finally, the sample module builds our application against the published gtk-kt module and copies the executable to the /app/bin folder as expected by Flatpak.

GitHub

View Github