mirror of
https://github.com/electron/node-gyp.git
synced 2025-08-15 12:58:19 +02:00
src: add support for locally installed headers (#2964)
Some linux distros allow headers to be installed through tools like rpm. If the runtime sets process.config.variables.use_prefix_to_find_headers, look for matching headers based on the directory set for the prefix in process.config.variables.prefix Signed-off-by: Michael Dawson <midawson@redhat.com> Co-authored-by: Luke Karrys <luke@lukekarrys.com>
This commit is contained in:
parent
7705a22f31
commit
329873141f
3 changed files with 151 additions and 1 deletions
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const { promises: fs } = require('graceful-fs')
|
||||
const { promises: fs, readFileSync } = require('graceful-fs')
|
||||
const path = require('path')
|
||||
const log = require('./log')
|
||||
const os = require('os')
|
||||
|
@ -13,6 +13,10 @@ const { findAccessibleSync } = require('./util')
|
|||
const { findPython } = require('./find-python')
|
||||
const { findVisualStudio } = win ? require('./find-visualstudio') : {}
|
||||
|
||||
const majorRe = /^#define NODE_MAJOR_VERSION (\d+)/m
|
||||
const minorRe = /^#define NODE_MINOR_VERSION (\d+)/m
|
||||
const patchRe = /^#define NODE_PATCH_VERSION (\d+)/m
|
||||
|
||||
async function configure (gyp, argv) {
|
||||
const buildDir = path.resolve('build')
|
||||
const configNames = ['config.gypi', 'common.gypi']
|
||||
|
@ -27,6 +31,28 @@ async function configure (gyp, argv) {
|
|||
// 'python' should be set by now
|
||||
process.env.PYTHON = python
|
||||
|
||||
if (!gyp.opts.nodedir &&
|
||||
process.config.variables.use_prefix_to_find_headers) {
|
||||
// check if the headers can be found using the prefix specified
|
||||
// at build time. Use them if they match the version expected
|
||||
const prefix = process.config.variables.node_prefix
|
||||
let availVersion
|
||||
try {
|
||||
const nodeVersionH = readFileSync(path.join(prefix,
|
||||
'include', 'node', 'node_version.h'), { encoding: 'utf8' })
|
||||
const major = nodeVersionH.match(majorRe)[1]
|
||||
const minor = nodeVersionH.match(minorRe)[1]
|
||||
const patch = nodeVersionH.match(patchRe)[1]
|
||||
availVersion = major + '.' + minor + '.' + patch
|
||||
} catch {}
|
||||
if (availVersion === release.version) {
|
||||
// ok version matches, use the headers
|
||||
gyp.opts.nodedir = prefix
|
||||
log.verbose('using local node headers based on prefix',
|
||||
'setting nodedir to ' + gyp.opts.nodedir)
|
||||
}
|
||||
}
|
||||
|
||||
if (gyp.opts.nodedir) {
|
||||
// --nodedir was specified. use that for the dev files
|
||||
nodeDir = gyp.opts.nodedir.replace(/^~/, os.homedir())
|
||||
|
|
123
test/test-configure-nodedir.js
Normal file
123
test/test-configure-nodedir.js
Normal file
|
@ -0,0 +1,123 @@
|
|||
'use strict'
|
||||
|
||||
const { describe, it } = require('mocha')
|
||||
const assert = require('assert')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
const gyp = require('../lib/node-gyp')
|
||||
const requireInject = require('require-inject')
|
||||
const semver = require('semver')
|
||||
|
||||
const versionSemver = semver.parse(process.version)
|
||||
|
||||
const configure = requireInject('../lib/configure', {
|
||||
'graceful-fs': {
|
||||
openSync: () => 0,
|
||||
closeSync: () => {},
|
||||
existsSync: () => true,
|
||||
readFileSync: () => '#define NODE_MAJOR_VERSION ' + versionSemver.major + '\n' +
|
||||
'#define NODE_MINOR_VERSION ' + versionSemver.minor + '\n' +
|
||||
'#define NODE_PATCH_VERSION ' + versionSemver.patch + '\n',
|
||||
promises: {
|
||||
stat: async () => ({}),
|
||||
mkdir: async () => {},
|
||||
writeFile: async () => {}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const configure2 = requireInject('../lib/configure', {
|
||||
'graceful-fs': {
|
||||
openSync: () => 0,
|
||||
closeSync: () => {},
|
||||
existsSync: () => true,
|
||||
readFileSync: () => '#define NODE_MAJOR_VERSION 8\n' +
|
||||
'#define NODE_MINOR_VERSION 0\n' +
|
||||
'#define NODE_PATCH_VERSION 0\n',
|
||||
promises: {
|
||||
stat: async () => ({}),
|
||||
mkdir: async () => {},
|
||||
writeFile: async () => {}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const SPAWN_RESULT = cb => ({ on: function () { cb() } })
|
||||
|
||||
const driveLetter = os.platform() === 'win32' ? `${process.cwd().split(path.sep)[0]}` : ''
|
||||
function checkTargetPath (target, value) {
|
||||
let targetPath = path.join(path.sep, target, 'include',
|
||||
'node', 'common.gypi')
|
||||
if (process.platform === 'win32') {
|
||||
targetPath = driveLetter + targetPath
|
||||
}
|
||||
|
||||
return targetPath.localeCompare(value) === 0
|
||||
}
|
||||
|
||||
describe('configure-nodedir', function () {
|
||||
it('configure nodedir with node-gyp command line', function (done) {
|
||||
const prog = gyp()
|
||||
prog.parseArgv(['dummy_prog', 'dummy_script', '--nodedir=' + path.sep + 'usr'])
|
||||
|
||||
prog.spawn = function (program, args) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (checkTargetPath('usr', args[i])) {
|
||||
return SPAWN_RESULT(done)
|
||||
}
|
||||
};
|
||||
assert.fail()
|
||||
}
|
||||
configure(prog, [], assert.fail)
|
||||
})
|
||||
|
||||
if (process.config.variables.use_prefix_to_find_headers) {
|
||||
it('use-prefix-to-find-headers build time option - match', function (done) {
|
||||
const prog = gyp()
|
||||
prog.parseArgv(['dummy_prog', 'dummy_script'])
|
||||
|
||||
prog.spawn = function (program, args) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const nodedir = process.config.variables.node_prefix
|
||||
if (checkTargetPath(nodedir, args[i])) {
|
||||
return SPAWN_RESULT(done)
|
||||
}
|
||||
};
|
||||
assert.fail()
|
||||
}
|
||||
configure(prog, [], assert.fail)
|
||||
})
|
||||
|
||||
it('use-prefix-to-find-headers build time option - no match', function (done) {
|
||||
const prog = gyp()
|
||||
prog.parseArgv(['dummy_prog', 'dummy_script'])
|
||||
|
||||
prog.spawn = function (program, args) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const nodedir = process.config.variables.node_prefix
|
||||
if (checkTargetPath(nodedir, args[i])) {
|
||||
assert.fail()
|
||||
}
|
||||
};
|
||||
return SPAWN_RESULT(done)
|
||||
}
|
||||
configure2(prog, [], assert.fail)
|
||||
})
|
||||
|
||||
it('use-prefix-to-find-headers build time option, target specified', function (done) {
|
||||
const prog = gyp()
|
||||
prog.parseArgv(['dummy_prog', 'dummy_script', '--target=8.0.0'])
|
||||
|
||||
prog.spawn = function (program, args) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const nodedir = process.config.variables.node_prefix
|
||||
if (checkTargetPath(nodedir, args[i])) {
|
||||
assert.fail()
|
||||
}
|
||||
};
|
||||
return SPAWN_RESULT(done)
|
||||
}
|
||||
configure(prog, [], assert.fail)
|
||||
})
|
||||
}
|
||||
})
|
|
@ -11,6 +11,7 @@ const configure = requireInject('../lib/configure', {
|
|||
'graceful-fs': {
|
||||
openSync: () => 0,
|
||||
closeSync: () => {},
|
||||
existsSync: () => {},
|
||||
promises: {
|
||||
stat: async () => ({}),
|
||||
mkdir: async () => {},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue