Skip to content

Commit 04c0c8a

Browse files
committed
fix: disable LTO for addon builds on Windows
1 parent 11a8b10 commit 04c0c8a

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

lib/create-config-gypi.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo, python }) {
9999
if (config.variables.clang === 1) {
100100
config.variables.clang = 0
101101
}
102+
// disable LTO for addon builds. node release builds may enable (thin) LTO,
103+
// which leaks clang/lld-only flags like -flto=thin and /opt:lldltojobs into
104+
// addons built with the default MSVC toolchain, which rejects those flags
105+
variables.enable_lto = 'false'
106+
variables.enable_thin_lto = 'false'
102107
}
103108

104109
// loop through the rest of the opts and add the unknown ones as variables.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Test configuration simulating a Node.js Windows release built with Thin LTO
2+
{
3+
'variables': {
4+
'enable_lto': 'true',
5+
'enable_thin_lto': 'true',
6+
'lto_jobs': '2'
7+
}
8+
}

test/test-create-config-gypi.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,25 @@ describe('create-config-gypi', function () {
5252
assert.strictEqual(config.variables.build_with_electron, undefined)
5353
})
5454

55+
it('config.gypi disables LTO for addon builds on Windows', async function () {
56+
const nodeDir = path.join(__dirname, 'fixtures', 'win-lto')
57+
58+
const prog = gyp()
59+
prog.parseArgv(['_', '_', `--nodedir=${nodeDir}`])
60+
61+
const originalPlatform = process.platform
62+
Object.defineProperty(process, 'platform', { value: 'win32' })
63+
try {
64+
const config = await getCurrentConfigGypi({ gyp: prog, nodeDir, vsInfo: {} })
65+
// thin LTO leaks clang/lld-only flags into the MSVC addon build, so it
66+
// must be disabled regardless of how node itself was built
67+
assert.strictEqual(config.variables.enable_lto, 'false')
68+
assert.strictEqual(config.variables.enable_thin_lto, 'false')
69+
} finally {
70+
Object.defineProperty(process, 'platform', { value: originalPlatform })
71+
}
72+
})
73+
5574
it('config.gypi parsing', function () {
5675
const str = "# Some comments\n{'variables': {'multiline': 'A'\n'B'}}"
5776
const config = parseConfigGypi(str)

0 commit comments

Comments
 (0)