import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.compose)
}
kotlin {
jvm {
withJava()
}
sourceSets {
val jvmMain by getting {
dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.material3)
implementation(compose.materialIconsExtended)
implementation(compose.desktop.currentOs)
implementation(project(":common"))
}
}
}
}
// Because of this bug you can not build for macOS and
// have the app image distribution format enabled.
// See:
// https://github.com/JetBrains/compose-multiplatform/issues/3814
val excludeAppImage = kotlin.run {
val excludeAppImage: String? by project
excludeAppImage == "true"
}
val appId = "com.artemchep.keyguard"
val macExtraPlistKeys: String
get() = """
CFBundleLocalizations
af_ZA
ca_ES
de_DE
es_ES
ja_JP
no_NO
pt_PT
sr_SP
uk_UA
zh_TW
ar_SA
cs_CZ
el_GR
fr_FR
it_IT
ko_KR
pl_PL
ro_RO
sv_SE
vi_VN
da_DK
en_US
en_GB
fi_FI
hu_HU
iw_IL
nl_NL
pt_BR
ru_RU
tr_TR
zh_CN
"""
compose.desktop {
application {
mainClass = "com.artemchep.keyguard.MainKt"
nativeDistributions {
macOS {
iconFile.set(project.file("icon.icns"))
entitlementsFile.set(project.file("default.entitlements"))
infoPlist {
this.extraKeysRawXml = macExtraPlistKeys
}
}
windows {
iconFile.set(project.file("icon.ico"))
}
linux {
iconFile.set(project.file("icon.png"))
}
// Try to go for native appearance as per:
// https://stackoverflow.com/a/70902920/1408535
jvmArgs(
"-Dapple.awt.application.appearance=system",
)
includeAllModules = true
val formats = listOfNotNull(
TargetFormat.Dmg,
TargetFormat.Msi,
TargetFormat.Deb,
TargetFormat.AppImage.takeUnless { excludeAppImage },
).toTypedArray()
targetFormats(*formats)
packageName = "Keyguard"
packageVersion = libs.versions.appVersionName.get()
macOS {
bundleID = "com.artemchep.keyguard"
signing {
val certIdentity = findProperty("cert_identity") as String?
if (certIdentity != null) {
println("Signing identity ${certIdentity.take(2)}****")
sign.set(true)
identity.set(certIdentity)
// The certificate should be added to the
// keychain by this time.
} else {
println("No signing identity!")
}
}
notarization {
val notarizationAppleId = findProperty("notarization_apple_id") as String?
?: "stub_apple_id"
val notarizationPassword = findProperty("notarization_password") as String?
?: "stub_password"
val notarizationAscProvider =
findProperty("notarization_asc_provider") as String?
?: "stub_asc_provider"
println("Notarization Apple Id ${notarizationAppleId.take(2)}****")
println("Notarization Password ${notarizationPassword.take(2)}****")
println("Notarization ASC Provider ${notarizationAscProvider.take(2)}****")
appleID.set(notarizationAppleId)
teamID.set(notarizationAscProvider)
password.set(notarizationPassword)
}
}
}
}
}
kotlin {
jvmToolchain(libs.versions.jdk.get().toInt())
}
//
// Flatpak
//
val flatpakDir = "$buildDir/flatpak"
val resourcesDir = "$projectDir/src/jvmMain/resources"
tasks.register("prepareFlatpak") {
dependsOn("packageAppImage")
doLast {
delete {
delete("$flatpakDir/bin/")
delete("$flatpakDir/lib/")
}
copy {
from("$buildDir/compose/binaries/main/app/Keyguard/")
into("$flatpakDir/")
exclude("$buildDir/compose/binaries/main/app/Keyguard/lib/runtime/legal")
}
copy {
from("$resourcesDir/icon.png")
into("$flatpakDir/")
}
copy {
from("$resourcesDir/flatpak/manifest.yml")
into("$flatpakDir/")
rename {
"$appId.yml"
}
}
copy {
from("$projectDir/src/jvmMain/resources/flatpak/icon.desktop")
into("$flatpakDir/")
rename {
"$appId.desktop"
}
}
}
}
tasks.register("bundleFlatpak") {
dependsOn("prepareFlatpak")
doLast {
exec {
workingDir(flatpakDir)
val buildCommand = listOf(
"flatpak-builder",
"--force-clean",
"--state-dir=build/flatpak-builder",
"--repo=build/flatpak-repo",
"build/flatpak-target",
"$appId.yml",
)
commandLine(buildCommand)
}
exec {
workingDir(flatpakDir)
val bundleCommand = listOf(
"flatpak",
"build-bundle",
"build/flatpak-repo",
"Keyguard.flatpak",
appId,
)
commandLine(bundleCommand)
}
}
}
tasks.register("installFlatpak") {
dependsOn("prepareFlatpak")
doLast {
exec {
workingDir(flatpakDir)
val installCommand = listOf(
"flatpak-builder",
"--install",
"--user",
"--force-clean",
"--state-dir=build/flatpak-builder",
"--repo=build/flatpak-repo",
"build/flatpak-target",
"$appId.yml",
)
commandLine(installCommand)
}
}
}
tasks.register("runFlatpak") {
dependsOn("installFlatpak")
doLast {
exec {
val runCommand = listOf(
"flatpak",
"run",
appId,
)
commandLine(runCommand)
}
}
}