mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-20 08:57:57 +00:00
fix(gui): strip host LD_LIBRARY_PATH from packaging + defensive GPU/icon fixes
Root cause of the packaged GUI crashing with SIGSEGV inside ld.so on user machines (segfault at fixed +0x1ff36, undefined symbols nspr_use_zone_allocator / localtime64): the build host had LD_LIBRARY_PATH polluted by a third-party runtime (/opt/cangjie), which electron-builder baked into the produced binary's dependency resolution. Clean machines without that library then fail in the dynamic loader before any app code runs. - Makefile: every gui-* pack target now runs under `env -u LD_LIBRARY_PATH` - main.js: app.disableHardwareAcceleration() before ready (avoids the common Chromium GPU-process SIGSEGV on hybrid-GPU/Wayland Linux hosts) - main.js: window icon reads from process.resourcesPath (real file, not asar) — asar-path icons are a known GTK segfault source on Linux
This commit is contained in:
18
Makefile
18
Makefile
@ -9,6 +9,12 @@ export GUI_DIR
|
||||
GUI_DIR=cmd/gui
|
||||
VERSION ?= $(shell git describe --tags --dirty 2>/dev/null || echo "0.1.0")
|
||||
|
||||
# Clean env for GUI packaging: the host may have LD_LIBRARY_PATH polluted by
|
||||
# third-party runtimes (e.g. /opt/cangjie) which electron-builder bakes into
|
||||
# the produced binary's DT_RPATH/dep resolution -> the packaged app then
|
||||
# SIGSEGVs inside ld.so on clean machines. Strip it for every pack step.
|
||||
CLEAN_PACK_ENV = env -u LD_LIBRARY_PATH
|
||||
|
||||
all: build
|
||||
|
||||
# ---- core binary (server users / embedded core) ----
|
||||
@ -26,23 +32,25 @@ gui-dev:
|
||||
|
||||
# build the embedded core into the GUI, then run electron-builder
|
||||
# targets: deb + AppImage (linux), rpm needs system rpmbuild
|
||||
# NOTE: run in a clean env (no LD_LIBRARY_PATH pollution) so the packaged
|
||||
# binary does not link against host-only libs and crash on user machines.
|
||||
gui-dist:
|
||||
@cd $(GUI_DIR) && npm run dist:linux
|
||||
@cd $(GUI_DIR) && $(CLEAN_PACK_ENV) npm run dist:linux
|
||||
|
||||
# deb only (for local sharing), rpm needs rpmbuild
|
||||
gui-deb:
|
||||
@cd $(GUI_DIR) && npm run dist:debian
|
||||
@cd $(GUI_DIR) && $(CLEAN_PACK_ENV) npm run dist:debian
|
||||
|
||||
# windows nsis installer: host-built core (needs apt install gcc-mingw-w64-x86-64 + wine)
|
||||
gui-win:
|
||||
@cd $(GUI_DIR) && npm run dist:win
|
||||
@cd $(GUI_DIR) && $(CLEAN_PACK_ENV) npm run dist:win
|
||||
|
||||
# windows nsis installer: full cross-build in docker (self-sufficient, no host mingw)
|
||||
gui-win-docker:
|
||||
@cd $(GUI_DIR) && ./scripts/dist-win-docker.sh
|
||||
@cd $(GUI_DIR) && $(CLEAN_PACK_ENV) ./scripts/dist-win-docker.sh
|
||||
|
||||
gui-dist-dir:
|
||||
@cd $(GUI_DIR) && npm run dist:dir
|
||||
@cd $(GUI_DIR) && $(CLEAN_PACK_ENV) npm run dist:dir
|
||||
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
@ -47,6 +47,15 @@ const CORE_EXE = path.join(
|
||||
"bin",
|
||||
process.platform === "win32" ? "llmsproxy.exe" : "llmsproxy",
|
||||
);
|
||||
// Packaged window icon: must be a REAL file on disk (extraResource), not an
|
||||
// asar path — Electron/GTK pulls BrowserWindow icons from the filesystem and
|
||||
// crashes (SIGSEGV) when given an asar virtual path on Linux.
|
||||
// Dev: cmd/gui/build/icon.png.
|
||||
const WINDOW_ICON = path.join(
|
||||
app.isPackaged ? process.resourcesPath : __dirname,
|
||||
"build",
|
||||
"icon.png",
|
||||
);
|
||||
// default port for the embedded core (configurable via settings)
|
||||
const DEFAULT_PORT = 8787;
|
||||
|
||||
@ -508,8 +517,9 @@ function createWindow() {
|
||||
const menu = Menu.buildFromTemplate([]);
|
||||
Menu.setApplicationMenu(menu);
|
||||
mainWindow = new BrowserWindow({
|
||||
// Window icon (taskbar/dock): same asset as the tray and package.
|
||||
icon: path.join(__dirname, "build", "icon.png"),
|
||||
// Window icon (taskbar/dock). Packaged: real file under resourcesPath (see
|
||||
// WINDOW_ICON) — an asar path here makes GTK segfault on Linux.
|
||||
icon: WINDOW_ICON,
|
||||
// GNOME taskbar icons match the window's WM_CLASS (lowercase
|
||||
// "modelrouter-gui") against StartupWMClass in the .desktop file.
|
||||
backgroundColor: "#1f2937",
|
||||
@ -639,6 +649,12 @@ ipcMain.handle("shell:openPath", (_, p) => {
|
||||
// window control from renderer uses preload -> ipcMain above
|
||||
|
||||
// ---------- bootstrap ----------
|
||||
// Defensive GPU handling: Electron's Chromium GPU process is a frequent
|
||||
// source of hard crashes (SIGSEGV) on Linux, especially on hybrid-GPU and
|
||||
// Wayland setups. The GUI host is an LLM management shell — a software
|
||||
// renderer is perfectly fine. Must run before app.whenReady.
|
||||
app.disableHardwareAcceleration();
|
||||
|
||||
const gotLock = app.requestSingleInstanceLock();
|
||||
if (gotLock) {
|
||||
app.on("second-instance", () => {
|
||||
|
||||
Reference in New Issue
Block a user