fix(macos): add GraalVM runtime dependency and initialize GraalVm in main function

This commit is contained in:
Kingkor Roy Tirtho 2026-10-19 18:50:27 +06:00
parent 069b586d44
commit 7ee3c70c96
3 changed files with 13 additions and 0 deletions

View File

@ -302,6 +302,7 @@ kotlin {
implementation(libs.jna)
implementation(libs.nucleus.core.runtime)
implementation(libs.nucleus.graalvm.runtime)
implementation(libs.nucleus.nucleus.application)
implementation(libs.nucleus.decorated.window.tao)
implementation(libs.compose.native.tray)
@ -401,6 +402,9 @@ nucleus.application {
nativeDistributions {
packageName = bundleId
// User-facing name (.app bundle, DMG productName, Launchpad/Dock); packageName above is the reverse-DNS id.
// The GraalVM DMG task reads only appName ?: packageName, not macOS.packageName
appName = if (isNightly) "Spotube Nightly" else "Spotube"
packageVersion = version
licenseFile = project.file("../LICENSE")
@ -435,6 +439,8 @@ nucleus.application {
macOS {
iconFile.set(project.file("$desktopIconDir/icon.icns"))
bundleID = if (isNightly) "$bundleId.nightly" else bundleId
dockName = appName
notarization {
}
@ -527,6 +533,8 @@ tasks.withType<Copy>().matching { it.name == "copyGraalvmAwtSoLibs" }.configureE
// Issue with compose plugin
// https://github.com/JetBrains/compose-hot-reload/blob/master/docs/Known_limitations.md#property-composeapplicationresourcesdir-is-null-when-running-hot-reload-tasks
tasks.withType<ComposeHotRun>().configureEach {
// Populates the resources dir below with the VLC natives (appResourcesRootDir); hot run doesn't depend on it by default
dependsOn("prepareAppResources")
jvmArgs(
"--enable-native-access=ALL-UNNAMED"
)

View File

@ -38,6 +38,7 @@ import spotube.composeapp.generated.resources.spotube_logo
import dev.nucleusframework.application.DecoratedWindow
import dev.nucleusframework.application.NucleusBackend
import dev.nucleusframework.application.nucleusApplication
import dev.nucleusframework.graalvm.GraalVmInitializer
import dev.nucleusframework.window.tao.TaoScreenGeometry
import io.github.vinceglb.filekit.FileKit
import kotlinx.coroutines.CoroutineScope
@ -132,6 +133,9 @@ private fun restoreWindowState(saved: PersistedWindowState?): PersistedWindowSta
@OptIn(ExperimentalComposeUiApi::class, FlowPreview::class)
fun main() {
// Native image only (no-op on the JVM): sets java.home, java.library.path and compose.application.resources.dir
// to the executable's dir, which the VLC loader needs to find the bundled libvlc
GraalVmInitializer.initialize()
FileKit.init(appId = "org.spotube.spotube")
initKoin()
NewPipeDownloader.init(KoinPathsProvider.paths)

View File

@ -129,6 +129,7 @@ murmurhash = { module = "com.goncalossilva:murmurhash", version.ref = "murmurhas
newpipe-extractor-kmp = { module = "io.github.yushosei:newpipe-extractor-kmp", version.ref = "newpipeExtractorKmp" }
newpipeextractor = { module = "com.github.teamnewpipe:NewPipeExtractor", version.ref = "newpipeextractor" }
nucleus-core-runtime = { module = "dev.nucleusframework:nucleus.core-runtime", version.ref = "nucleusNucleusApplication" }
nucleus-graalvm-runtime = { module = "dev.nucleusframework:nucleus.graalvm-runtime", version.ref = "nucleusNucleusApplication" }
nucleus-decorated-window-tao = { module = "dev.nucleusframework:nucleus.decorated-window-tao", version.ref = "nucleusNucleusApplication" }
nucleus-media-control = { module = "dev.nucleusframework:nucleus.media-control", version.ref = "nucleusNucleusApplication" }
nucleus-nucleus-application = { module = "dev.nucleusframework:nucleus.nucleus-application", version.ref = "nucleusNucleusApplication" }