fix(desktop): degrade get-windows on Windows ARM64
(cherry picked from commit 6997b5a97e72aa1ffc98533aaa100e84857b1fbe)
This commit is contained in:
@@ -144,11 +144,10 @@ export default async function beforePack(context) {
|
||||
await stageNodePty({ platform, arch: archName })
|
||||
console.log(`[before-pack] re-staged node-pty for target ${platform}-${archName}`)
|
||||
}
|
||||
// get-windows' native payload is per-platform, not per-arch (the macOS
|
||||
// helper is universal, Windows stages every prebuilt binding dir), so
|
||||
// it re-stages for the universal target too.
|
||||
stageGetWindows({ platform })
|
||||
console.log(`[before-pack] re-staged get-windows for target ${platform}`)
|
||||
// The macOS helper is universal, while Windows bindings are arch-specific.
|
||||
// Pass the target arch so an ARM64 package never stages an x64 binding.
|
||||
stageGetWindows({ platform, arch: archName })
|
||||
console.log(`[before-pack] re-staged get-windows for target ${platform}-${archName}`)
|
||||
}
|
||||
} catch (err) {
|
||||
// This one SHOULD fail the build — a missing/wrong native binary for the
|
||||
|
||||
@@ -437,7 +437,7 @@ const GET_WINDOWS_VERSION = '9.3.0'
|
||||
export function stageGetWindowsInto(
|
||||
srcRoot,
|
||||
destRoot,
|
||||
{ platform = process.platform, rebuild } = {}
|
||||
{ platform = process.platform, arch = process.arch, rebuild } = {}
|
||||
) {
|
||||
// The STAGED_WINDOWS_JS rewrite mirrors this exact version's export surface.
|
||||
// A version bump must fail the build here until the rewrite is re-verified —
|
||||
@@ -490,11 +490,20 @@ export function stageGetWindowsInto(
|
||||
? readdirSync(bindingRoot).filter(
|
||||
(dir) =>
|
||||
dir.includes(`-${platform}-`) &&
|
||||
dir.endsWith(`-${arch}`) &&
|
||||
existsSync(join(bindingRoot, dir, 'node-get-windows.node'))
|
||||
)
|
||||
: []
|
||||
let bindingDirs = scanBindingDirs()
|
||||
if (bindingDirs.length === 0 && typeof rebuild === 'function') {
|
||||
if (bindingDirs.length === 0 && arch === 'arm64') {
|
||||
// get-windows 9.3.0 publishes win32 prebuilds for ia32/x64 only.
|
||||
// The staged windows.js deliberately fails soft when binding/ is absent,
|
||||
// so preserve the desktop build and disable only window enumeration.
|
||||
console.warn(
|
||||
'[stage-native-deps] get-windows has no win32-arm64 prebuilt binding; ' +
|
||||
'staging the fail-soft JS surface without native window enumeration.'
|
||||
)
|
||||
} else if (bindingDirs.length === 0 && typeof rebuild === 'function') {
|
||||
// A plain `npm install` won't re-run an install script for a package
|
||||
// that is already on disk, so every checkout that installed while
|
||||
// get-windows was missing from allowScripts stays bricked even after
|
||||
@@ -505,9 +514,9 @@ export function stageGetWindowsInto(
|
||||
rebuild()
|
||||
bindingDirs = scanBindingDirs()
|
||||
}
|
||||
if (bindingDirs.length === 0) {
|
||||
if (bindingDirs.length === 0 && arch !== 'arm64') {
|
||||
throw new Error(
|
||||
'[stage-native-deps] get-windows has no win32 prebuilt binding under lib/binding. ' +
|
||||
`[stage-native-deps] get-windows has no win32-${arch} prebuilt binding under lib/binding. ` +
|
||||
'Recover from the checkout root with:\n' +
|
||||
' npm install-scripts approve get-windows\n' +
|
||||
' npm rebuild get-windows'
|
||||
@@ -546,7 +555,11 @@ function rebuildGetWindowsViaNpm() {
|
||||
}
|
||||
|
||||
export function stageGetWindows(
|
||||
{ platform = process.platform, resolveRoot = resolveGetWindowsRoot } = {}
|
||||
{
|
||||
platform = process.platform,
|
||||
arch = process.arch,
|
||||
resolveRoot = resolveGetWindowsRoot
|
||||
} = {}
|
||||
) {
|
||||
const srcRoot = resolveRoot()
|
||||
const destRoot = resolve(projectRoot, 'dist/node_modules/get-windows')
|
||||
@@ -575,12 +588,12 @@ export function stageGetWindows(
|
||||
// has nothing to gain from the rebuild.
|
||||
const rebuild =
|
||||
platform === 'win32' && process.platform === 'win32' ? rebuildGetWindowsViaNpm : undefined
|
||||
return stageGetWindowsInto(srcRoot, destRoot, { platform, rebuild })
|
||||
return stageGetWindowsInto(srcRoot, destRoot, { platform, arch, rebuild })
|
||||
}
|
||||
|
||||
// Allow direct CLI invocation: node scripts/stage-native-deps.mjs [platform] [arch]
|
||||
if (isMain(import.meta.url)) {
|
||||
const [platform, arch] = process.argv.slice(2)
|
||||
stageNodePty({ platform, arch })
|
||||
stageGetWindows({ platform })
|
||||
stageGetWindows({ platform, arch })
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ test('win32 staging skips the darwin binding the tarball bundles on every platfo
|
||||
]
|
||||
})
|
||||
|
||||
stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32' })
|
||||
stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', arch: 'x64' })
|
||||
|
||||
assert.ok(existsSync(join(destRoot, 'lib', 'binding', 'napi-9-win32-unknown-x64', 'node-get-windows.node')))
|
||||
assert.ok(!existsSync(join(destRoot, 'lib', 'binding', 'napi-9-darwin-unknown-arm64')))
|
||||
@@ -411,7 +411,7 @@ test('win32 staging rejects a binding dir that claims win32 but holds a foreign
|
||||
})
|
||||
|
||||
assert.throws(
|
||||
() => stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32' }),
|
||||
() => stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', arch: 'x64' }),
|
||||
/expected win32, got darwin/
|
||||
)
|
||||
} finally {
|
||||
@@ -419,7 +419,7 @@ test('win32 staging rejects a binding dir that claims win32 but holds a foreign
|
||||
}
|
||||
})
|
||||
|
||||
test('win32 staging fails when only foreign bindings exist', () => {
|
||||
test('win32-x64 staging fails when only foreign bindings exist', () => {
|
||||
const tmp = fs.mkdtempSync(join(os.tmpdir(), 'hermes-stage-'))
|
||||
try {
|
||||
const srcRoot = join(tmp, 'get-windows')
|
||||
@@ -430,14 +430,36 @@ test('win32 staging fails when only foreign bindings exist', () => {
|
||||
})
|
||||
|
||||
assert.throws(
|
||||
() => stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32' }),
|
||||
/no win32 prebuilt binding/
|
||||
() => stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', arch: 'x64' }),
|
||||
/no win32-x64 prebuilt binding/
|
||||
)
|
||||
} finally {
|
||||
fs.rmSync(tmp, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
test('win32-arm64 staging omits incompatible bindings and keeps the fail-soft JS surface', () => {
|
||||
const tmp = fs.mkdtempSync(join(os.tmpdir(), 'hermes-stage-'))
|
||||
try {
|
||||
const srcRoot = join(tmp, 'get-windows')
|
||||
const destRoot = join(tmp, 'dest')
|
||||
|
||||
makeFakeGetWindows(srcRoot, {
|
||||
bindings: [
|
||||
{ dir: 'napi-9-darwin-unknown-arm64', platform: 'darwin' },
|
||||
{ dir: 'napi-9-win32-unknown-x64', platform: 'win32' }
|
||||
]
|
||||
})
|
||||
|
||||
stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', arch: 'arm64' })
|
||||
|
||||
assert.ok(existsSync(join(destRoot, 'lib', 'windows.js')))
|
||||
assert.ok(!existsSync(join(destRoot, 'lib', 'binding')))
|
||||
} finally {
|
||||
fs.rmSync(tmp, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
test('win32 staging self-heals through the rebuild hook when the binding is missing', () => {
|
||||
const tmp = fs.mkdtempSync(join(os.tmpdir(), 'hermes-stage-'))
|
||||
try {
|
||||
@@ -457,7 +479,7 @@ test('win32 staging self-heals through the rebuild hook when the binding is miss
|
||||
)
|
||||
}
|
||||
|
||||
stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', rebuild })
|
||||
stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', arch: 'x64', rebuild })
|
||||
|
||||
assert.equal(calls, 1)
|
||||
assert.ok(
|
||||
@@ -477,7 +499,12 @@ test('win32 staging reports the recovery steps when the rebuild hook produces no
|
||||
makeFakeGetWindows(srcRoot, { bindings: [] })
|
||||
|
||||
assert.throws(
|
||||
() => stageGetWindowsInto(srcRoot, destRoot, { platform: 'win32', rebuild: () => {} }),
|
||||
() =>
|
||||
stageGetWindowsInto(srcRoot, destRoot, {
|
||||
platform: 'win32',
|
||||
arch: 'x64',
|
||||
rebuild: () => {}
|
||||
}),
|
||||
/npm rebuild get-windows/
|
||||
)
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user