11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst fs = require('graceful-fs').promises
41cb0ef41Sopenharmony_ciconst log = require('./log')
51cb0ef41Sopenharmony_ciconst path = require('path')
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cifunction parseConfigGypi (config) {
81cb0ef41Sopenharmony_ci  // translated from tools/js2c.py of Node.js
91cb0ef41Sopenharmony_ci  // 1. string comments
101cb0ef41Sopenharmony_ci  config = config.replace(/#.*/g, '')
111cb0ef41Sopenharmony_ci  // 2. join multiline strings
121cb0ef41Sopenharmony_ci  config = config.replace(/'$\s+'/mg, '')
131cb0ef41Sopenharmony_ci  // 3. normalize string literals from ' into "
141cb0ef41Sopenharmony_ci  config = config.replace(/'/g, '"')
151cb0ef41Sopenharmony_ci  return JSON.parse(config)
161cb0ef41Sopenharmony_ci}
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciasync function getBaseConfigGypi ({ gyp, nodeDir }) {
191cb0ef41Sopenharmony_ci  // try reading $nodeDir/include/node/config.gypi first when:
201cb0ef41Sopenharmony_ci  // 1. --dist-url or --nodedir is specified
211cb0ef41Sopenharmony_ci  // 2. and --force-process-config is not specified
221cb0ef41Sopenharmony_ci  const useCustomHeaders = gyp.opts.nodedir || gyp.opts.disturl || gyp.opts['dist-url']
231cb0ef41Sopenharmony_ci  const shouldReadConfigGypi = useCustomHeaders && !gyp.opts['force-process-config']
241cb0ef41Sopenharmony_ci  if (shouldReadConfigGypi && nodeDir) {
251cb0ef41Sopenharmony_ci    try {
261cb0ef41Sopenharmony_ci      const baseConfigGypiPath = path.resolve(nodeDir, 'include/node/config.gypi')
271cb0ef41Sopenharmony_ci      const baseConfigGypi = await fs.readFile(baseConfigGypiPath)
281cb0ef41Sopenharmony_ci      return parseConfigGypi(baseConfigGypi.toString())
291cb0ef41Sopenharmony_ci    } catch (err) {
301cb0ef41Sopenharmony_ci      log.warn('read config.gypi', err.message)
311cb0ef41Sopenharmony_ci    }
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  // fallback to process.config if it is invalid
351cb0ef41Sopenharmony_ci  return JSON.parse(JSON.stringify(process.config))
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciasync function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo, python }) {
391cb0ef41Sopenharmony_ci  const config = await getBaseConfigGypi({ gyp, nodeDir })
401cb0ef41Sopenharmony_ci  if (!config.target_defaults) {
411cb0ef41Sopenharmony_ci    config.target_defaults = {}
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci  if (!config.variables) {
441cb0ef41Sopenharmony_ci    config.variables = {}
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  const defaults = config.target_defaults
481cb0ef41Sopenharmony_ci  const variables = config.variables
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  // don't inherit the "defaults" from the base config.gypi.
511cb0ef41Sopenharmony_ci  // doing so could cause problems in cases where the `node` executable was
521cb0ef41Sopenharmony_ci  // compiled on a different machine (with different lib/include paths) than
531cb0ef41Sopenharmony_ci  // the machine where the addon is being built to
541cb0ef41Sopenharmony_ci  defaults.cflags = []
551cb0ef41Sopenharmony_ci  defaults.defines = []
561cb0ef41Sopenharmony_ci  defaults.include_dirs = []
571cb0ef41Sopenharmony_ci  defaults.libraries = []
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  // set the default_configuration prop
601cb0ef41Sopenharmony_ci  if ('debug' in gyp.opts) {
611cb0ef41Sopenharmony_ci    defaults.default_configuration = gyp.opts.debug ? 'Debug' : 'Release'
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  if (!defaults.default_configuration) {
651cb0ef41Sopenharmony_ci    defaults.default_configuration = 'Release'
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  // set the target_arch variable
691cb0ef41Sopenharmony_ci  variables.target_arch = gyp.opts.arch || process.arch || 'ia32'
701cb0ef41Sopenharmony_ci  if (variables.target_arch === 'arm64') {
711cb0ef41Sopenharmony_ci    defaults.msvs_configuration_platform = 'ARM64'
721cb0ef41Sopenharmony_ci    defaults.xcode_configuration_platform = 'arm64'
731cb0ef41Sopenharmony_ci  }
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  // set the node development directory
761cb0ef41Sopenharmony_ci  variables.nodedir = nodeDir
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  // set the configured Python path
791cb0ef41Sopenharmony_ci  variables.python = python
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  // disable -T "thin" static archives by default
821cb0ef41Sopenharmony_ci  variables.standalone_static_library = gyp.opts.thin ? 0 : 1
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  if (process.platform === 'win32') {
851cb0ef41Sopenharmony_ci    defaults.msbuild_toolset = vsInfo.toolset
861cb0ef41Sopenharmony_ci    if (vsInfo.sdk) {
871cb0ef41Sopenharmony_ci      defaults.msvs_windows_target_platform_version = vsInfo.sdk
881cb0ef41Sopenharmony_ci    }
891cb0ef41Sopenharmony_ci    if (variables.target_arch === 'arm64') {
901cb0ef41Sopenharmony_ci      if (vsInfo.versionMajor > 15 ||
911cb0ef41Sopenharmony_ci          (vsInfo.versionMajor === 15 && vsInfo.versionMajor >= 9)) {
921cb0ef41Sopenharmony_ci        defaults.msvs_enable_marmasm = 1
931cb0ef41Sopenharmony_ci      } else {
941cb0ef41Sopenharmony_ci        log.warn('Compiling ARM64 assembly is only available in\n' +
951cb0ef41Sopenharmony_ci          'Visual Studio 2017 version 15.9 and above')
961cb0ef41Sopenharmony_ci      }
971cb0ef41Sopenharmony_ci    }
981cb0ef41Sopenharmony_ci    variables.msbuild_path = vsInfo.msBuild
991cb0ef41Sopenharmony_ci  }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  // loop through the rest of the opts and add the unknown ones as variables.
1021cb0ef41Sopenharmony_ci  // this allows for module-specific configure flags like:
1031cb0ef41Sopenharmony_ci  //
1041cb0ef41Sopenharmony_ci  //   $ node-gyp configure --shared-libxml2
1051cb0ef41Sopenharmony_ci  Object.keys(gyp.opts).forEach(function (opt) {
1061cb0ef41Sopenharmony_ci    if (opt === 'argv') {
1071cb0ef41Sopenharmony_ci      return
1081cb0ef41Sopenharmony_ci    }
1091cb0ef41Sopenharmony_ci    if (opt in gyp.configDefs) {
1101cb0ef41Sopenharmony_ci      return
1111cb0ef41Sopenharmony_ci    }
1121cb0ef41Sopenharmony_ci    variables[opt.replace(/-/g, '_')] = gyp.opts[opt]
1131cb0ef41Sopenharmony_ci  })
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  return config
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ciasync function createConfigGypi ({ gyp, buildDir, nodeDir, vsInfo, python }) {
1191cb0ef41Sopenharmony_ci  const configFilename = 'config.gypi'
1201cb0ef41Sopenharmony_ci  const configPath = path.resolve(buildDir, configFilename)
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  log.verbose('build/' + configFilename, 'creating config file')
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  const config = await getCurrentConfigGypi({ gyp, nodeDir, vsInfo, python })
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  // ensures that any boolean values in config.gypi get stringified
1271cb0ef41Sopenharmony_ci  function boolsToString (k, v) {
1281cb0ef41Sopenharmony_ci    if (typeof v === 'boolean') {
1291cb0ef41Sopenharmony_ci      return String(v)
1301cb0ef41Sopenharmony_ci    }
1311cb0ef41Sopenharmony_ci    return v
1321cb0ef41Sopenharmony_ci  }
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  log.silly('build/' + configFilename, config)
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  // now write out the config.gypi file to the build/ dir
1371cb0ef41Sopenharmony_ci  const prefix = '# Do not edit. File was generated by node-gyp\'s "configure" step'
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  const json = JSON.stringify(config, boolsToString, 2)
1401cb0ef41Sopenharmony_ci  log.verbose('build/' + configFilename, 'writing out config file: %s', configPath)
1411cb0ef41Sopenharmony_ci  await fs.writeFile(configPath, [prefix, json, ''].join('\n'))
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  return configPath
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_cimodule.exports = {
1471cb0ef41Sopenharmony_ci  createConfigGypi,
1481cb0ef41Sopenharmony_ci  parseConfigGypi,
1491cb0ef41Sopenharmony_ci  getCurrentConfigGypi
1501cb0ef41Sopenharmony_ci}
151