Repository navigation
Expand file tree
/
Copy pathconveyor.conf
More file actions
242 lines (212 loc) · 12.7 KB
/
Copy pathconveyor.conf
File metadata and controls
242 lines (212 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// SimpMusic — Hydraulic Conveyor packaging config (Conveyor 2.0+)
//
// Distribution: installers (Mac .dmg via Mac runner wrap, Windows .msix
// + .appinstaller + .exe wrapper, Linux .AppImage) are uploaded to
// GitHub Releases manually. Conveyor's site.base-url auto-resolves to
// the `releases/latest/download/` URL pattern via `app.vcs-url`, so
// the generated download.html / `.appinstaller` reference the correct
// asset URLs without any extra hosting. Auto-update is disabled (see
// `updates = none` below) — users re-download for new versions.
//
// Pattern adapted from https://github.com/zacharee/Bifrost (KMP +
// Conveyor 2.0 reference).
// CI / local must run `./gradlew :desktopApp:writeConveyorConfig` BEFORE
// invoking Conveyor. The shell-include form (`include "#!..."`) was
// removed because Conveyor parses Gradle stdout as HOCON, and Sentry-
// related `println("Full build detected, ...")` in composeApp+androidApp
// configuration phase corrupts that stdout when `isFullBuild=true` is
// set in CI → "Key 'Full build detected' may not be followed by ','".
include required("desktopApp/generated.conveyor.conf")
// NOTE: deliberately NOT including hydraulic's extract-native-libraries.conf.
// That helper extracts every JAR-embedded native into the top-level lib/app
// AND keeps the source tree intact, so every bundled native gets duplicated
// (with the old VLC plugin set that took output from 989 MB to 1.4 GB).
// Nothing needs it:
// 1. MpvLibrary walks up from the JAR to find mpv/ at runtime
// 2. JNA's own per-JAR native unpacking still runs without the helper
app {
// fsname / display-name / rdns-name are appended by the doLast block in
// desktopApp/build.gradle.kts's writeConveyorConfig customisation.
vendor = "maxrave-dev"
description = "A FOSS YouTube Music client built with Compose Multiplatform."
license = "GPL-3.0-or-later"
// Open source = free Conveyor. Setting `vcs-url` to the public source
// repository qualifies SimpMusic for the OSS tier and removes the paid
// license requirement. See https://hydraulic.dev/pricing.html — "free
// for open source projects if you set the app.vcs-url key to where your
// source repository can be found."
//
// Per the same clause we must advertise "Packaged with Conveyor" + link
// to hydraulic.dev somewhere user-visible (download page, README, or
// about screen). The auto-generated download site already embeds the
// required badge — see TODO in docs/conveyor-local-test.md.
vcs-url = "https://github.com/maxrave-dev/SimpMusic"
// Single PNG source → Conveyor auto-derives .icns / .ico / png variants
// for mac, windows, linux. Native .icns / .ico inputs are silently
// ignored by Conveyor 22.0 (it always re-encodes from raster source).
icons = "composeApp/icon/circle_app_icon.png"
// site.base-url auto-inferred from `vcs-url` above to the latest GitHub
// Release for this repo (Conveyor 22.0+ behaviour, per the March 2024
// blog update). Manually setting it to the releases LIST page broke
// the .appinstaller / .exe wrapper URLs Conveyor generates.
//
// updates = none → Conveyor does not wire Sparkle (Mac) or the
// background .appinstaller update check (Windows). Releases are still
// shipped through GitHub Releases manually; users re-download to
// upgrade. Flip to `background` later if/when we want silent updates.
updates = none
site {
consistency-checks = warn
}
// Custom URI schemes to register the app for. "simpmusic" backs the deep links
// from simpmusic.org; "wordbyword" is the Last.fm auth callback, whose scheme is
// fixed by the callback URL registered on the Last.fm API account.
//
// This key MUST stay at the top level of `app`. Conveyor binds url-schemes on
// AppConfig, not on MacConfig/WindowsConfig/LinuxConfig — compare
// `MacConfigAccess.getUrlSchemes()` (reads appConfig) with the
// `getFileAssociations()` right next to it (reads mac). We previously set
// `mac.url-schemes` / `windows.url-schemes` / `linux.url-schemes`; HOCON accepts
// unknown keys silently, so all three sat inert and the packaged apps carried NO
// CFBundleURLTypes at all — verified by diffing two mac-app builds that differed
// only in where this key was written. Nothing ever registered, not even
// "simpmusic", from May 2026 until this was moved.
url-schemes = [ "simpmusic", "wordbyword" ]
// Explicit machines list. Two architectures explicitly dropped because
// of missing native dependencies upstream:
//
// • linux.aarch64.glibc — dropped when VLC was the backend, because
// VideoLAN ships no prebuilt Linux ARM binary and the
// mahozad/vlc-plugins-linux artifact was amd64-only. That blocker
// died with VLC: mpv-AppImage does publish an aarch64 build, so this
// is worth revisiting once an ARM libmpv slice is staged.
//
// • windows.aarch64 — androidx.sqlite:sqlite-bundled-jvm 2.6.2 (and
// even 2.7.0-alpha05) lacks a windows_arm64 sqliteJni.dll. The
// bundled driver fails Room init with "Cannot find a suitable
// SQLite binary for windows 11 | aarch64", which we cannot work
// around without building the native ourselves. Windows 11 ARM
// can run the x64 msix under Prism emulation in the meantime —
// re-enable once Google ships the win-arm64 native upstream.
machines = [
"windows.amd64",
"mac.amd64", "mac.aarch64",
"linux.amd64.glibc",
]
// Per-arch libmpv staged by `./gradlew :composeApp:mpvSetupAll`. Each
// per-machine installer carries only the slice it actually needs.
// MpvLibrary resolves this `mpv/` folder by walking up from the JAR
// location — Conveyor does not set compose.application.resources.dir, so
// the packaged app cannot rely on that property.
windows.amd64.inputs += { from = "mpv-natives/windows-x64", to = "mpv" }
mac.amd64.inputs += { from = "mpv-natives/macos-x64", to = "mpv" }
mac.aarch64.inputs += { from = "mpv-natives/macos-arm64", to = "mpv" }
linux.amd64.inputs += { from = "mpv-natives/linux-x64", to = "mpv" }
// --- Per-OS overrides -----------------------------------------------------
// Linux: produce the relocatable directory tree (`linux-app` task) only.
// Conveyor 2.0 dropped native AppImage support — we wrap the tree with
// appimagetool via `./gradlew :desktopApp:packageConveyorAppImage` to
// ship a one-for-all-distros .AppImage. Set `targets = []` so the `site`
// task doesn't try to emit .deb / .tar.gz that we don't ship anyway.
linux.amd64.targets = [ ]
// NOTE: we don't ship the Conveyor Windows .zip (duplicates msix
// payload), .appinstaller (we don't host an update site, URL is 404),
// or .exe installer wrapper (also fetches the missing .appinstaller
// and fails with HRESULT 0x80190194). Setting
// `windows.<arch>.targets = ["windows-msix"]` has no effect on the
// `site` task for Windows machines (verified locally), so we filter at
// the workflow upload step instead and bundle the .msix with our own
// scripts/windows/install.bat for offline install.
mac {
// The rounded-square logo (the Android launcher's), drawn in the same frame as the circle one
// the other platforms keep.
icons = "composeApp/icon/rounded_app_icon.png"
info-plist.LSApplicationCategoryType = "public.app-category.music"
info-plist.UIBackgroundModes = [ "audio", "fetch", "processing" ]
// Turn off Apple's "nano" malloc zone — the macOS counterpart of the
// MALLOC_ARENA_MAX cap the AppImage's AppRun sets for glibc.
//
// The nano zone serves allocations under 256 bytes from its own region and
// has a history of not coalescing what it frees, so the region only grows;
// Electron and Chrome both hit this. mpv/FFmpeg allocate small structures
// constantly on every track change, which is exactly that pattern.
//
// LSEnvironment is applied by LaunchServices, so it covers Finder/Dock/
// Spotlight/`open` launches — i.e. every normal launch of an installed
// .app — but NOT running Contents/MacOS/... directly from a shell.
//
// Declaring this dict also pins the process PATH to the bare
// "/usr/bin:/bin:/usr/sbin:/sbin". Checked before adding: the only
// ProcessBuilder use on this path is the Windows-only powershell/wmic VM
// probe in DesktopApp.kt, and link opening goes through Desktop.browse(),
// which LaunchServices resolves without consulting PATH. Revisit this if
// the macOS build ever shells out to a binary outside those four dirs.
info-plist.LSEnvironment.MallocNanoZone = "0"
// Raised from the implicit 11.0 when the desktop backend moved from VLC to mpv.
// mpv's own macOS release builds target macOS 15: 96 of the 98 bundled arm64 dylibs
// declare minos 15.0, and on Intel libmpv itself does — so Conveyor refuses to package
// an app claiming 11.0 ("Required macOS version mismatch"). VideoLAN still built for
// older systems, which is the only reason 11.0 worked before. There is no mpv artifact
// for macOS < 15 covering both architectures, so this is the floor.
info-plist.LSMinimumSystemVersion = 15.0
}
windows {
start-menu.group = "SimpMusic"
// DEBUG ONLY — remove before shipping a release.
// A Windows GUI binary has no console attached, so everything the app writes to
// stdout/stderr is discarded and a startup failure leaves nothing to look at.
// This attaches a console window that shows both.
// console = true
}
linux {
// Entries belong INSIDE the "Desktop Entry" group — that group is the .desktop
// file's real section, and it is where Conveyor puts Name/Exec/Icon/Comment.
// These three used to sit one level up (desktop-file.Categories, etc.), which
// put them beside the group rather than in it, so none of them reached the
// generated file — same silent-misplacement bug as url-schemes above.
desktop-file."Desktop Entry" {
"Comment[en]" = "A FOSS YouTube Music client"
Categories = "AudioVideo;Audio;Player;Music;"
// Must match the runtime WM_CLASS forced by forceLinuxWmClass() in
// desktopApp/.../Main.kt. Was "java-lang-Thread" (a stale guess that broke
// once AWT started initializing on a coroutine worker thread).
StartupWMClass = "SimpMusic"
}
}
// --- Build settings -------------------------------------------------------
compression-level = low
jvm {
modules = "ALL-MODULE-PATH"
// extract-native-libraries = true // disabled: duplicates the bundled
// natives by extracting them flat while keeping the original tree.
// Not needed — MpvLibrary walks up from the JAR location to find mpv/.
options += "--add-opens=java.base/java.nio=ALL-UNNAMED"
// Without an explicit ceiling the JVM sizes its heap at 1/4 of physical RAM,
// so on a 32 GB machine it will happily grow to several GB before the GC feels
// any pressure — which is why resident memory sat around 1 GB. A music player's
// live set is nowhere near that; the cap makes the GC collect on a sane cadence.
options += "-Xmx512m"
// The G1 heap-trim trio (-XX:MinHeapFreeRatio=20, -XX:MaxHeapFreeRatio=40,
// -XX:G1PeriodicGCInterval=60000) used to live here, handing the unused half of the
// heap back to the OS (measured: 204 MB committed vs 104 MB live). It was removed
// 2026-08-28, NOT because it stopped being right: Conveyor's launcher packs the JVM
// options and the computed app arguments into a fixed 16384-byte buffer, the quickjs
// dependency's jars pushed the total over it ("Your JVM arguments and constant app
// arguments together are too large"), and these three flags were the only bytes that
// could go without opening modules or dropping the -Xmx cap. Idle RSS will sit a bit
// higher until Hydraulic enlarges the buffer — put the trio back when that ships.
}
jvm.mac.options += "--add-opens=java.desktop/sun.awt=ALL-UNNAMED"
jvm.mac.options += "--add-opens=java.desktop/sun.lwawt=ALL-UNNAMED"
jvm.mac.options += "--add-opens=java.desktop/sun.lwawt.macosx=ALL-UNNAMED"
// Linux: allow forceLinuxWmClass() in Main.kt to reflectively overwrite
// sun.awt.X11.XToolkit.awtAppClassName so the dock shows "SimpMusic" instead
// of the coroutine-worker class name. JDK 17+ blocks setAccessible on sun.*
// without this open, and the reflection then silently no-ops.
jvm.linux.options += "--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED"
}
conveyor.compatibility-level = 21
// Loosen disk cache requirement (default 5 GB free) — local dev machines
// often have less headroom while caches keep growing. CI runners with
// fresh disks won't be affected.
conveyor.disk-cache.minimum-free-disk-space = 1 GB