feat: implement cross-compilation support for native addons and clean up non-target binaries
All checks were successful
Release Electron App / release-desktop (push) Successful in 11m5s
All checks were successful
Release Electron App / release-desktop (push) Successful in 11m5s
This commit is contained in:
@@ -69,6 +69,34 @@ const config: ForgeConfig = {
|
|||||||
env: { ...process.env, npm_config_nodedir: '' },
|
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-<platform>-<arch>-*).
|
// vectordb uses platform-specific optional deps (@lancedb/vectordb-<platform>-<arch>-*).
|
||||||
// npm install on Linux only pulls the Linux variant. Force-install the target's.
|
// npm install on Linux only pulls the Linux variant. Force-install the target's.
|
||||||
const platformNativePackages: Record<string, Record<string, string>> = {
|
const platformNativePackages: Record<string, Record<string, string>> = {
|
||||||
@@ -85,7 +113,6 @@ const config: ForgeConfig = {
|
|||||||
'@lancedb/vectordb-darwin-arm64': '',
|
'@lancedb/vectordb-darwin-arm64': '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const targetKey = `${platform}-${arch}`;
|
|
||||||
const nativePkgs = platformNativePackages[targetKey];
|
const nativePkgs = platformNativePackages[targetKey];
|
||||||
if (nativePkgs) {
|
if (nativePkgs) {
|
||||||
// Remove wrong-platform lancedb native packages
|
// Remove wrong-platform lancedb native packages
|
||||||
@@ -110,8 +137,7 @@ const config: ForgeConfig = {
|
|||||||
// Remove cross-platform prebuilt binaries that don't match the target.
|
// Remove cross-platform prebuilt binaries that don't match the target.
|
||||||
// Packages like @github/copilot ship prebuilds for all platforms;
|
// Packages like @github/copilot ship prebuilds for all platforms;
|
||||||
// keeping foreign-arch .node files breaks rpmbuild's strip step.
|
// keeping foreign-arch .node files breaks rpmbuild's strip step.
|
||||||
const targetDir = `${platform}-${arch}`;
|
const nodeModulesPath = path.join(buildPath, 'node_modules');
|
||||||
const nmPath = path.join(buildPath, 'node_modules');
|
|
||||||
const findPrebuilds = (dir: string): string[] => {
|
const findPrebuilds = (dir: string): string[] => {
|
||||||
const results: string[] = [];
|
const results: string[] = [];
|
||||||
if (!fs.existsSync(dir)) return results;
|
if (!fs.existsSync(dir)) return results;
|
||||||
@@ -128,15 +154,36 @@ const config: ForgeConfig = {
|
|||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const prebuildsDir of findPrebuilds(nmPath)) {
|
for (const prebuildsDir of findPrebuilds(nodeModulesPath)) {
|
||||||
for (const entry of fs.readdirSync(prebuildsDir)) {
|
for (const entry of fs.readdirSync(prebuildsDir)) {
|
||||||
if (entry !== targetDir) {
|
if (entry !== targetKey) {
|
||||||
const fullPath = path.join(prebuildsDir, entry);
|
const fullPath = path.join(prebuildsDir, entry);
|
||||||
fs.rmSync(fullPath, { recursive: true, force: true });
|
fs.rmSync(fullPath, { recursive: true, force: true });
|
||||||
console.log(`[forge] Removed non-target prebuild: ${entry}`);
|
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<string, string> = {
|
||||||
|
'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: [
|
makers: [
|
||||||
|
|||||||
Reference in New Issue
Block a user