You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
4.6 KiB
147 lines
4.6 KiB
'use strict' |
|
|
|
const fs = require('graceful-fs') |
|
const log = require('npmlog') |
|
const path = require('path') |
|
|
|
function parseConfigGypi (config) { |
|
// translated from tools/js2c.py of Node.js |
|
// 1. string comments |
|
config = config.replace(/#.*/g, '') |
|
// 2. join multiline strings |
|
config = config.replace(/'$\s+'/mg, '') |
|
// 3. normalize string literals from ' into " |
|
config = config.replace(/'/g, '"') |
|
return JSON.parse(config) |
|
} |
|
|
|
async function getBaseConfigGypi ({ gyp, nodeDir }) { |
|
// try reading $nodeDir/include/node/config.gypi first when: |
|
// 1. --dist-url or --nodedir is specified |
|
// 2. and --force-process-config is not specified |
|
const useCustomHeaders = gyp.opts.nodedir || gyp.opts.disturl || gyp.opts['dist-url'] |
|
const shouldReadConfigGypi = useCustomHeaders && !gyp.opts['force-process-config'] |
|
if (shouldReadConfigGypi && nodeDir) { |
|
try { |
|
const baseConfigGypiPath = path.resolve(nodeDir, 'include/node/config.gypi') |
|
const baseConfigGypi = await fs.promises.readFile(baseConfigGypiPath) |
|
return parseConfigGypi(baseConfigGypi.toString()) |
|
} catch (err) { |
|
log.warn('read config.gypi', err.message) |
|
} |
|
} |
|
|
|
// fallback to process.config if it is invalid |
|
return JSON.parse(JSON.stringify(process.config)) |
|
} |
|
|
|
async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo }) { |
|
const config = await getBaseConfigGypi({ gyp, nodeDir }) |
|
if (!config.target_defaults) { |
|
config.target_defaults = {} |
|
} |
|
if (!config.variables) { |
|
config.variables = {} |
|
} |
|
|
|
const defaults = config.target_defaults |
|
const variables = config.variables |
|
|
|
// don't inherit the "defaults" from the base config.gypi. |
|
// doing so could cause problems in cases where the `node` executable was |
|
// compiled on a different machine (with different lib/include paths) than |
|
// the machine where the addon is being built to |
|
defaults.cflags = [] |
|
defaults.defines = [] |
|
defaults.include_dirs = [] |
|
defaults.libraries = [] |
|
|
|
// set the default_configuration prop |
|
if ('debug' in gyp.opts) { |
|
defaults.default_configuration = gyp.opts.debug ? 'Debug' : 'Release' |
|
} |
|
|
|
if (!defaults.default_configuration) { |
|
defaults.default_configuration = 'Release' |
|
} |
|
|
|
// set the target_arch variable |
|
variables.target_arch = gyp.opts.arch || process.arch || 'ia32' |
|
if (variables.target_arch === 'arm64') { |
|
defaults.msvs_configuration_platform = 'ARM64' |
|
defaults.xcode_configuration_platform = 'arm64' |
|
} |
|
|
|
// set the node development directory |
|
variables.nodedir = nodeDir |
|
|
|
// disable -T "thin" static archives by default |
|
variables.standalone_static_library = gyp.opts.thin ? 0 : 1 |
|
|
|
if (process.platform === 'win32') { |
|
defaults.msbuild_toolset = vsInfo.toolset |
|
if (vsInfo.sdk) { |
|
defaults.msvs_windows_target_platform_version = vsInfo.sdk |
|
} |
|
if (variables.target_arch === 'arm64') { |
|
if (vsInfo.versionMajor > 15 || |
|
(vsInfo.versionMajor === 15 && vsInfo.versionMajor >= 9)) { |
|
defaults.msvs_enable_marmasm = 1 |
|
} else { |
|
log.warn('Compiling ARM64 assembly is only available in\n' + |
|
'Visual Studio 2017 version 15.9 and above') |
|
} |
|
} |
|
variables.msbuild_path = vsInfo.msBuild |
|
} |
|
|
|
// loop through the rest of the opts and add the unknown ones as variables. |
|
// this allows for module-specific configure flags like: |
|
// |
|
// $ node-gyp configure --shared-libxml2 |
|
Object.keys(gyp.opts).forEach(function (opt) { |
|
if (opt === 'argv') { |
|
return |
|
} |
|
if (opt in gyp.configDefs) { |
|
return |
|
} |
|
variables[opt.replace(/-/g, '_')] = gyp.opts[opt] |
|
}) |
|
|
|
return config |
|
} |
|
|
|
async function createConfigGypi ({ gyp, buildDir, nodeDir, vsInfo }) { |
|
const configFilename = 'config.gypi' |
|
const configPath = path.resolve(buildDir, configFilename) |
|
|
|
log.verbose('build/' + configFilename, 'creating config file') |
|
|
|
const config = await getCurrentConfigGypi({ gyp, nodeDir, vsInfo }) |
|
|
|
// ensures that any boolean values in config.gypi get stringified |
|
function boolsToString (k, v) { |
|
if (typeof v === 'boolean') { |
|
return String(v) |
|
} |
|
return v |
|
} |
|
|
|
log.silly('build/' + configFilename, config) |
|
|
|
// now write out the config.gypi file to the build/ dir |
|
const prefix = '# Do not edit. File was generated by node-gyp\'s "configure" step' |
|
|
|
const json = JSON.stringify(config, boolsToString, 2) |
|
log.verbose('build/' + configFilename, 'writing out config file: %s', configPath) |
|
await fs.promises.writeFile(configPath, [prefix, json, ''].join('\n')) |
|
|
|
return configPath |
|
} |
|
|
|
module.exports = createConfigGypi |
|
module.exports.test = { |
|
parseConfigGypi: parseConfigGypi, |
|
getCurrentConfigGypi: getCurrentConfigGypi |
|
}
|
|
|