mirror of
https://github.com/electron/node-gyp.git
synced 2025-09-15 13:43:40 +02:00

* fix: create Python symlink only during builds, and clean it up after
Previously in b9ddcd5bbd
this was created
during configuration, and the symlink persisted indefinitely. This
causes problems with many tools that do not expect a codebase to include
symlinks to external absolute paths.
This PR largely reverts that commit, and instead writes the path to
link to into the config, and then creates the symlink only temporarily
during the build process, always deleting it afterwards.
* assert install_path == self.output, f"{install_path} != {self.output}"
---------
Co-authored-by: Christian Clauss <cclauss@me.com>
150 lines
4.6 KiB
JavaScript
150 lines
4.6 KiB
JavaScript
'use strict'
|
|
|
|
const fs = require('graceful-fs')
|
|
const log = require('./log')
|
|
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, python }) {
|
|
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
|
|
|
|
// set the configured Python path
|
|
variables.python = python
|
|
|
|
// 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, python }) {
|
|
const configFilename = 'config.gypi'
|
|
const configPath = path.resolve(buildDir, configFilename)
|
|
|
|
log.verbose('build/' + configFilename, 'creating config file')
|
|
|
|
const config = await getCurrentConfigGypi({ gyp, nodeDir, vsInfo, python })
|
|
|
|
// 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,
|
|
getCurrentConfigGypi
|
|
}
|