diff --git a/forge.config.ts b/forge.config.ts index 1a7ef37..edb499e 100644 --- a/forge.config.ts +++ b/forge.config.ts @@ -69,6 +69,34 @@ const config: ForgeConfig = { env: { ...process.env, npm_config_nodedir: '' }, }); + // When cross-compiling, native addons (better-sqlite3, keytar) are built + // for the build machine (Linux). Re-download prebuilts for the target. + const targetKey = `${platform}-${arch}`; + const buildKey = `${process.platform}-${process.arch}`; + if (targetKey !== buildKey) { + console.log(`[forge] Cross-compiling: ${buildKey} → ${targetKey}`); + const electronVersion = JSON.parse( + fs.readFileSync(path.resolve(__dirname, 'node_modules', 'electron', 'package.json'), 'utf-8'), + ).version; + + // Use prebuild-install to fetch correct native binaries + const prebuildModules = ['better-sqlite3', 'keytar']; + for (const mod of prebuildModules) { + const modDir = path.join(buildPath, 'node_modules', mod); + if (fs.existsSync(modDir)) { + console.log(`[forge] Downloading ${mod} prebuilt for ${targetKey} (Electron ${electronVersion})...`); + try { + execSync( + `npx --yes prebuild-install -r electron -t ${electronVersion} --platform ${platform} --arch ${arch} --verbose`, + { cwd: modDir, stdio: 'inherit' }, + ); + } catch (e) { + console.warn(`[forge] prebuild-install failed for ${mod}, trying node-gyp rebuild...`); + } + } + } + } + // vectordb uses platform-specific optional deps (@lancedb/vectordb---*). // npm install on Linux only pulls the Linux variant. Force-install the target's. const platformNativePackages: Record> = { @@ -85,7 +113,6 @@ const config: ForgeConfig = { '@lancedb/vectordb-darwin-arm64': '', }, }; - const targetKey = `${platform}-${arch}`; const nativePkgs = platformNativePackages[targetKey]; if (nativePkgs) { // Remove wrong-platform lancedb native packages @@ -110,8 +137,7 @@ const config: ForgeConfig = { // Remove cross-platform prebuilt binaries that don't match the target. // Packages like @github/copilot ship prebuilds for all platforms; // keeping foreign-arch .node files breaks rpmbuild's strip step. - const targetDir = `${platform}-${arch}`; - const nmPath = path.join(buildPath, 'node_modules'); + const nodeModulesPath = path.join(buildPath, 'node_modules'); const findPrebuilds = (dir: string): string[] => { const results: string[] = []; if (!fs.existsSync(dir)) return results; @@ -128,15 +154,36 @@ const config: ForgeConfig = { return results; }; - for (const prebuildsDir of findPrebuilds(nmPath)) { + for (const prebuildsDir of findPrebuilds(nodeModulesPath)) { for (const entry of fs.readdirSync(prebuildsDir)) { - if (entry !== targetDir) { + if (entry !== targetKey) { const fullPath = path.join(prebuildsDir, entry); fs.rmSync(fullPath, { recursive: true, force: true }); console.log(`[forge] Removed non-target prebuild: ${entry}`); } } } + + // @github/copilot ships @teddyzhu/clipboard-* platform packages outside + // of prebuilds/. Remove non-target variants to avoid bundling wrong binaries. + const clipboardDir = path.join(buildPath, 'node_modules', '@github', 'copilot', 'clipboard', 'node_modules', '@teddyzhu'); + if (fs.existsSync(clipboardDir)) { + const targetClipboardMap: Record = { + 'win32-x64': 'clipboard-win32-x64-msvc', + 'win32-arm64': 'clipboard-win32-arm64-msvc', + 'linux-x64': 'clipboard-linux-x64-gnu', + 'linux-arm64': 'clipboard-linux-arm64-gnu', + 'darwin-x64': 'clipboard-darwin-x64', + 'darwin-arm64': 'clipboard-darwin-arm64', + }; + const wantedPkg = targetClipboardMap[targetKey]; + for (const entry of fs.readdirSync(clipboardDir)) { + if (entry.startsWith('clipboard-') && entry !== wantedPkg) { + fs.rmSync(path.join(clipboardDir, entry), { recursive: true, force: true }); + console.log(`[forge] Removed non-target clipboard package: @teddyzhu/${entry}`); + } + } + } }, }, makers: [