UwU 1 день назад
Родитель
Сommit
9b194d6b2c
2 измененных файлов с 53 добавлено и 1 удалено
  1. 22 1
      src/main/services/lwe.service.test.ts
  2. 31 0
      src/main/services/lwe.service.ts

+ 22 - 1
src/main/services/lwe.service.test.ts

@@ -12,7 +12,7 @@ vi.mock('./config.service', () => ({
   getDisablePuppetAnimation: () => false
 }))
 
-const { buildHotswapLines, parseCustomArgs } = await import('./lwe.service')
+const { buildCleanBuildEnv, buildHotswapLines, parseCustomArgs } = await import('./lwe.service')
 
 describe('parseCustomArgs', () => {
   it('splits on whitespace and keeps quoted values together', () => {
@@ -64,3 +64,24 @@ describe('buildHotswapLines', () => {
     ])
   })
 })
+
+describe('buildCleanBuildEnv', () => {
+  it('drops AppImage mount entries from path lists and the AppImage variables', () => {
+    const saved = { ...process.env }
+    process.env.APPDIR = '/tmp/.mount_WE-ManAbc123'
+    process.env.PATH = '/tmp/.mount_WE-ManAbc123:/tmp/.mount_WE-ManAbc123/usr/sbin:/usr/local/bin:/usr/bin'
+    process.env.XDG_DATA_DIRS = '/tmp/.mount_WE-ManAbc123/usr/share'
+    process.env.LD_LIBRARY_PATH = '/tmp/.mount_WE-ManAbc123/usr/lib'
+    process.env.HOME = '/home/user'
+    try {
+      const env = buildCleanBuildEnv()
+      expect(env.PATH).toBe('/usr/local/bin:/usr/bin')
+      expect(env.XDG_DATA_DIRS).toBeUndefined()
+      expect(env.LD_LIBRARY_PATH).toBeUndefined()
+      expect(env.APPDIR).toBeUndefined()
+      expect(env.HOME).toBe('/home/user')
+    } finally {
+      process.env = saved
+    }
+  })
+})

+ 31 - 0
src/main/services/lwe.service.ts

@@ -50,14 +50,42 @@ const execFileAsync = promisify(execFile)
  * that into the engine's build lets CMake's library search pick up we_manager's own bundled
  * libEGL.so etc. and cache that dead path in CMakeCache.txt once the mount is gone.
  */
+const APPIMAGE_MOUNT = /^\/tmp\/\.mount_[^/]+(\/|$)/
+
+function isAppImagePath(entry: string, appDir: string | undefined): boolean {
+  if (appDir && (entry === appDir || entry.startsWith(`${appDir}/`))) return true
+  return APPIMAGE_MOUNT.test(entry)
+}
+
 export function buildCleanBuildEnv(): NodeJS.ProcessEnv {
   const env = { ...process.env }
+  const appDir = env.APPDIR
   for (const key of ['LD_LIBRARY_PATH', 'LD_PRELOAD', 'APPDIR', 'APPIMAGE', 'OWD', 'ARGV0']) {
     delete env[key]
   }
+  // AppRun also puts the mount on PATH (and XDG_DATA_DIRS etc.). CMake's find_library searches PATH
+  // entries, so it picked Electron's bundled libEGL.so from /tmp/.mount_*, a path gone after a relaunch
+  for (const [key, value] of Object.entries(env)) {
+    if (!value || !value.includes('/')) continue
+    const entries = value.split(':')
+    if (!entries.some((entry) => isAppImagePath(entry, appDir))) continue
+    const kept = entries.filter((entry) => !isAppImagePath(entry, appDir))
+    if (kept.length > 0) env[key] = kept.join(':')
+    else delete env[key]
+  }
   return env
 }
 
+/** A reused build dir whose CMakeCache.txt points into an AppImage mount has to be configured from scratch. */
+function dropPoisonedCmakeCache(cmakeBuild: string): boolean {
+  const cachePath = path.join(cmakeBuild, 'CMakeCache.txt')
+  let cache: string
+  try { cache = fs.readFileSync(cachePath, 'utf8') } catch { return false }
+  if (!/\/tmp\/\.mount_[^/\s]+/.test(cache)) return false
+  fs.rmSync(cachePath, { force: true })
+  return true
+}
+
 const LWE_BINARY = 'linux-wallpaperengine'
 const BUILD_DIR = path.join(os.tmpdir(), 'lwe-build')
 
@@ -367,6 +395,9 @@ export async function installLwe(win: BrowserWindow): Promise<void> {
 
     const cmakeBuild = path.join(BUILD_DIR, 'build')
     fs.mkdirSync(cmakeBuild, { recursive: true })
+    if (dropPoisonedCmakeCache(cmakeBuild)) {
+      send({ stage: 'building', message: 'Discarding a CMake cache that referenced an AppImage mount...', percentage: 20 })
+    }
 
     const buildEnv = buildCleanBuildEnv()