@flun/nodejs-mobile-gyp 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +7 -25
  2. package/LICENSE +9 -4
  3. package/README.md +198 -132
  4. package/addon.gypi +1 -1
  5. package/bin/node-gyp.js +6 -5
  6. package/gyp/README.md +5 -3
  7. package/gyp/data/win/large-pdb-shim.cc +1 -1
  8. package/gyp/gyp +1 -1
  9. package/gyp/gyp.bat +1 -1
  10. package/gyp/gyp_main.py +1 -1
  11. package/gyp/pylib/gyp/MSVSNew.py +1 -1
  12. package/gyp/pylib/gyp/MSVSProject.py +1 -1
  13. package/gyp/pylib/gyp/MSVSSettings.py +1 -1
  14. package/gyp/pylib/gyp/MSVSToolFile.py +1 -1
  15. package/gyp/pylib/gyp/MSVSUserFile.py +1 -1
  16. package/gyp/pylib/gyp/MSVSUtil.py +1 -1
  17. package/gyp/pylib/gyp/MSVSVersion.py +1 -1
  18. package/gyp/pylib/gyp/__init__.py +1 -1
  19. package/gyp/pylib/gyp/common.py +1 -1
  20. package/gyp/pylib/gyp/easy_xml.py +1 -1
  21. package/gyp/pylib/gyp/flock_tool.py +1 -1
  22. package/gyp/pylib/gyp/generator/analyzer.py +1 -1
  23. package/gyp/pylib/gyp/generator/android.py +1 -1
  24. package/gyp/pylib/gyp/generator/cmake.py +1 -1
  25. package/gyp/pylib/gyp/generator/compile_commands_json.py +1 -1
  26. package/gyp/pylib/gyp/generator/dump_dependency_json.py +1 -1
  27. package/gyp/pylib/gyp/generator/eclipse.py +1 -1
  28. package/gyp/pylib/gyp/generator/gypd.py +1 -1
  29. package/gyp/pylib/gyp/generator/gypsh.py +1 -1
  30. package/gyp/pylib/gyp/generator/make.py +23 -12
  31. package/gyp/pylib/gyp/generator/msvs.py +3 -3
  32. package/gyp/pylib/gyp/generator/ninja.py +1 -1
  33. package/gyp/pylib/gyp/generator/xcode.py +1 -1
  34. package/gyp/pylib/gyp/input.py +1 -1
  35. package/gyp/pylib/gyp/mac_tool.py +1 -1
  36. package/gyp/pylib/gyp/msvs_emulation.py +1 -1
  37. package/gyp/pylib/gyp/ninja_syntax.py +1 -1
  38. package/gyp/pylib/gyp/simple_copy.py +1 -1
  39. package/gyp/pylib/gyp/win_tool.py +1 -1
  40. package/gyp/pylib/gyp/xcode_emulation.py +5 -5
  41. package/gyp/pylib/gyp/xcode_ninja.py +1 -1
  42. package/gyp/pylib/gyp/xcodeproj_file.py +1 -1
  43. package/gyp/pylib/gyp/xml_fix.py +1 -1
  44. package/gyp/pylib/packaging/LICENSE +1 -1
  45. package/gyp/pylib/packaging/LICENSE.APACHE +1 -1
  46. package/gyp/pylib/packaging/LICENSE.BSD +1 -1
  47. package/gyp/pylib/packaging/__init__.py +1 -1
  48. package/gyp/pylib/packaging/_elffile.py +1 -1
  49. package/gyp/pylib/packaging/_manylinux.py +1 -1
  50. package/gyp/pylib/packaging/_musllinux.py +1 -1
  51. package/gyp/pylib/packaging/_parser.py +1 -1
  52. package/gyp/pylib/packaging/_structures.py +1 -1
  53. package/gyp/pylib/packaging/_tokenizer.py +1 -1
  54. package/gyp/pylib/packaging/markers.py +1 -1
  55. package/gyp/pylib/packaging/metadata.py +1 -1
  56. package/gyp/pylib/packaging/requirements.py +1 -1
  57. package/gyp/pylib/packaging/specifiers.py +1 -1
  58. package/gyp/pylib/packaging/tags.py +1 -1
  59. package/gyp/pylib/packaging/utils.py +1 -1
  60. package/gyp/pylib/packaging/version.py +1 -1
  61. package/lib/Find-VisualStudio.cs +1 -1
  62. package/lib/build.js +16 -16
  63. package/lib/clean.js +2 -2
  64. package/lib/configure.js +20 -17
  65. package/lib/create-config-gypi.js +8 -8
  66. package/lib/download.js +3 -3
  67. package/lib/find-node-directory.js +9 -9
  68. package/lib/find-python.js +14 -14
  69. package/lib/find-visualstudio.js +19 -19
  70. package/lib/install.js +22 -21
  71. package/lib/list.js +1 -1
  72. package/lib/log.js +2 -2
  73. package/lib/node-gyp.js +7 -7
  74. package/lib/process-release.js +14 -14
  75. package/lib/rebuild.js +1 -1
  76. package/lib/remove.js +2 -2
  77. package/lib/util.js +5 -4
  78. package/package.json +1 -1
  79. package/src/win_delay_load_hook.cc +1 -1
package/lib/build.js CHANGED
@@ -9,14 +9,14 @@ import fsSync from 'fs';
9
9
 
10
10
  const fs = gracefulFs.promises,
11
11
  _hostIsWindows = process.platform === 'win32',
12
- // Android 交叉编译即使宿主是 Windows,也必须走 make(make-android 生成器)
12
+ // Android 交叉编译即使宿主是 Windows,也必须走 make(make-android 生成器)
13
13
  _isAndroidCrossBuild = process.env.npm_config_platform === 'android' || process.env.npm_config_format === 'make-android',
14
- // win 在此文件中语义为"使用 MSBuild":仅 Windows 宿主且非 Android 交叉编译
14
+ // win 在此文件中语义为"使用 MSBuild":仅 Windows 宿主且非 Android 交叉编译
15
15
  win = _hostIsWindows && !_isAndroidCrossBuild,
16
16
  /**
17
17
  * Windows 上 GNU make 需要 sh.exe 来执行 Makefile 里的 Unix 命令
18
- * (printf / xargs / rm 等)。优先复用 Git for Windows 自带的 usr/bin,
19
- * 避免要求用户额外安装 MSYS2。通过 "where git" 反推,不硬编码路径。
18
+ * (printf / xargs / rm 等);优先复用 Git for Windows 自带的 usr/bin,
19
+ * 避免要求用户额外安装 MSYS2;通过 "where git" 反推,不硬编码路径;
20
20
  */
21
21
  findWindowsShellDir = () => {
22
22
  if (process.platform !== 'win32') return null;
@@ -24,7 +24,7 @@ const fs = gracefulFs.promises,
24
24
  try { return fsSync.existsSync(path.join(dir, 'sh.exe')) ? dir : null } catch { return null }
25
25
  };
26
26
  const toShDir = (gitRoot) => tryShDir(path.join(gitRoot, 'usr', 'bin'));
27
- // 1) 注册表:Git for Windows 安装时必写,与 PATH 无关(最可靠)
27
+ // 1) 注册表:Git for Windows 安装时必写,与 PATH 无关(最可靠)
28
28
  const reg = process.env.SystemRoot ? path.join(process.env.SystemRoot, 'System32', 'reg.exe') : 'reg.exe';
29
29
  for (const hive of ['HKLM', 'HKCU']) {
30
30
  for (const key of ['SOFTWARE\\GitForWindows', 'SOFTWARE\\WOW6432Node\\GitForWindows']) {
@@ -40,7 +40,7 @@ const fs = gracefulFs.promises,
40
40
  } catch { }
41
41
  }
42
42
  }
43
- // 2) which.sync(PATH 中能找到 git 时可用)
43
+ // 2) which.sync(PATH 中能找到 git 时可用)
44
44
  try {
45
45
  const gitPath = which.sync('git');
46
46
  if (gitPath) {
@@ -49,7 +49,7 @@ const fs = gracefulFs.promises,
49
49
  if (r) return r;
50
50
  }
51
51
  } catch { }
52
- // 3) PATH 中找 git.exe,再反推 ../usr/bin
52
+ // 3) PATH 中找 git.exe,再反推 ../usr/bin
53
53
  for (const pd of (process.env.PATH || '').split(';')) {
54
54
  if (!pd) continue;
55
55
  try {
@@ -97,11 +97,11 @@ const fs = gracefulFs.promises,
97
97
  if (win && !verbose) argv.push('/clp:Verbosity=minimal');
98
98
  if (win) argv.push('/nologo'); // Windows 上关闭 Microsoft logo
99
99
 
100
- // 指定构建类型,默认 Release
100
+ // 指定构建类型,默认 Release
101
101
  if (win) {
102
102
  // 把 .gypi 配置中的 target_arch 转换为 MSBuild 的 /Platform
103
- // 因为表示"32 位 Intel"的方式很多,默认按此处理
104
- // 注意:msbuild 的 Condition 字符串相等比较不区分大小写
103
+ // 因为表示"32 位 Intel"的方式很多,默认按此处理
104
+ // 注意:msbuild 的 Condition 字符串相等比较不区分大小写
105
105
  const archLower = arch.toLowerCase(), p = archLower === 'x64' ? 'x64' : (archLower === 'arm' ? 'ARM'
106
106
  : (archLower === 'arm64' ? 'ARM64' : 'Win32'));
107
107
  argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
@@ -122,13 +122,13 @@ const fs = gracefulFs.promises,
122
122
  }
123
123
 
124
124
  if (win) {
125
- // 用户是否指定了自己的 .sln 文件?
125
+ // 用户是否指定了自己的 .sln 文件?
126
126
  const hasSln = argv.some(arg => path.extname(arg) === '.sln');
127
127
  if (!hasSln) argv.unshift(gyp.opts.solution || guessedSolution);
128
128
  }
129
129
 
130
130
  if (!win) {
131
- // 把构建期依赖的符号链接(如 Python)加入 PATH
131
+ // 把构建期依赖的符号链接(如 Python)加入 PATH
132
132
  buildBinsDir = path.resolve('build', 'node_gyp_bins');
133
133
  if (_hostIsWindows) {
134
134
  const shellDir = findWindowsShellDir();
@@ -136,7 +136,7 @@ const fs = gracefulFs.promises,
136
136
  process.env.PATH = `${shellDir};${process.env.PATH}`;
137
137
  log.verbose('bin shell', `prepended ${shellDir} to PATH for make`);
138
138
  } else {
139
- log.warn('bin shell', 'no sh.exe found; GNU make 的 Unix 命令可能失败。建议安装 Git for Windows');
139
+ log.warn('bin shell', 'no sh.exe found; GNU make 的 Unix 命令可能失败;建议安装 Git for Windows');
140
140
  }
141
141
  }
142
142
  process.env.PATH = _hostIsWindows
@@ -145,7 +145,7 @@ const fs = gracefulFs.promises,
145
145
  await fs.mkdir(buildBinsDir, { recursive: true });
146
146
 
147
147
  if (_hostIsWindows) {
148
- // Windows 无 python3 名称,且创建符号链接需要管理员权限;改用 .cmd 桥接
148
+ // Windows 无 python3 名称,且创建符号链接需要管理员权限;改用 .cmd 桥接
149
149
  const shimPath = path.join(buildBinsDir, 'python3.cmd');
150
150
  await fs.writeFile(shimPath, `@echo off\r\n"${python}" %*\r\n`);
151
151
  log.verbose('bin shims', `created python3.cmd shim to "${python}" and added to PATH`);
@@ -176,7 +176,7 @@ const fs = gracefulFs.promises,
176
176
  doWhich = async () => {
177
177
  // Windows 使用 node-gyp configure 提供的 msbuild
178
178
  if (win) {
179
- if (!config.variables.msbuild_path) throw new Error('MSBuild 未设置,请先运行 `node-gyp configure`');
179
+ if (!config.variables.msbuild_path) throw new Error('MSBuild 未设置,请先运行 `node-gyp configure`');
180
180
  command = config.variables.msbuild_path, log.verbose('using MSBuild:', command), await doBuild();
181
181
  return;
182
182
  }
@@ -190,7 +190,7 @@ const fs = gracefulFs.promises,
190
190
  */
191
191
  findSolutionFile = async () => {
192
192
  const files = await glob('build/*.sln')
193
- if (files.length === 0) throw new Error('未找到 *.sln 文件,是否运行过 configure?');
193
+ if (files.length === 0) throw new Error('未找到 *.sln 文件,是否运行过 configure?');
194
194
  guessedSolution = files[0], log.verbose('found first Solution file', guessedSolution), await doWhich();
195
195
  },
196
196
  /**
package/lib/clean.js CHANGED
@@ -3,7 +3,7 @@ import * as log from './log.js';
3
3
 
4
4
  const fs = gracefulFs.promises,
5
5
  /**
6
- * 清理:删除 build 目录
6
+ * 清理:删除 build 目录
7
7
  */
8
8
  clean = async (gyp, argv) => {
9
9
  const buildDir = 'build';
@@ -13,4 +13,4 @@ const fs = gracefulFs.promises,
13
13
  }
14
14
 
15
15
  clean.usage = 'Removes any generated build files and the "out" dir';
16
- export { clean };
16
+ export { clean };
package/lib/configure.js CHANGED
@@ -10,9 +10,10 @@ import { findAccessibleSync } from './util.js';
10
10
  import { PythonFinder } from './find-python.js';
11
11
  import { fileURLToPath } from 'url';
12
12
 
13
- const fs = gracefulFs.promises, win = process.platform === 'win32', __dirname = path.dirname(fileURLToPath(import.meta.url));
13
+ const fs = gracefulFs.promises, win = process.platform === 'win32',
14
+ __dirname = path.dirname(fileURLToPath(import.meta.url));
14
15
 
15
- // 条件加载:仅在 Windows 上需要
16
+ // 条件加载:仅在 Windows 上需要
16
17
  let findVisualStudio = null, nodeDir, vsInfo = null;
17
18
  if (win) {
18
19
  const { VisualStudioFinder } = await import('./find-visualstudio.js');
@@ -20,7 +21,7 @@ if (win) {
20
21
  }
21
22
 
22
23
  /**
23
- * 生成构建文件(Makefile / MSVC 工程)
24
+ * 生成构建文件(Makefile / MSVC 工程)
24
25
  */
25
26
  const configure = async (gyp, argv) => {
26
27
  const buildDir = path.resolve('build'), configNames = ['config.gypi', 'common.gypi'], configs = [],
@@ -40,7 +41,7 @@ const configure = async (gyp, argv) => {
40
41
  }
41
42
 
42
43
  configs.forEach(config => argv.push('-I', config)); // 引入所有找到的 .gypi 文件
43
- // AIX 和 z/OS 需要设置导出文件路径,其中包含链接所需符号
44
+ // AIX 和 z/OS 需要设置导出文件路径,其中包含链接所需符号
44
45
  let nodeExpFile, nodeRootDir, candidates, logprefix = 'find exports file';
45
46
  if (process.platform === 'aix' || process.platform === 'os390' || process.platform === 'os400') {
46
47
  const ext = process.platform === 'os390' ? 'x' : 'exp';
@@ -62,7 +63,7 @@ const configure = async (gyp, argv) => {
62
63
  }
63
64
  }
64
65
 
65
- // z/OS 需要设置 zoslib 头文件目录,其中包含 v8config.h 引用的头文件
66
+ // z/OS 需要设置 zoslib 头文件目录,其中包含 v8config.h 引用的头文件
66
67
  let zoslibIncDir;
67
68
  if (process.platform === 'os390') {
68
69
  logprefix = "find zoslib's zos-base.h:";
@@ -110,7 +111,8 @@ const configure = async (gyp, argv) => {
110
111
  if (win) outputDir = buildDir; // Windows 需要绝对路径
111
112
  const nodeGypDir = path.resolve(__dirname, '..');
112
113
 
113
- let nodeLibFile = path.join(nodeDir, !gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)', release.name + '.lib');
114
+ let nodeLibFile = path.join(nodeDir,
115
+ !gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)', release.name + '.lib');
114
116
 
115
117
  argv.push('-I', addonGypi), argv.push('-I', commonGypi), argv.push('-Dlibrary=shared_library');
116
118
  argv.push('-Dvisibility=default'), argv.push('-Dnode_root_dir=' + nodeDir);
@@ -120,18 +122,18 @@ const configure = async (gyp, argv) => {
120
122
  }
121
123
  argv.push('-Dnode_gyp_dir=' + nodeGypDir);
122
124
 
123
- // 这样做是为了让 Cygwin 环境正常工作,否则未转义的 '\' 会被吃掉,
124
- // 导致路径错误,如 c:parentFolderfolderanotherFolder 而非 c:\parentFolder\folder\anotherFolder
125
+ // 这样做是为了让 Cygwin 环境正常工作,否则未转义的 '\' 会被吃掉,
126
+ // 导致路径错误,如 c:parentFolderfolderanotherFolder 而非 c:\parentFolder\folder\anotherFolder
125
127
  if (win) nodeLibFile = nodeLibFile.replace(/\\/g, '\\\\');
126
128
  argv.push('-Dnode_lib_file=' + nodeLibFile), argv.push('-Dmodule_root_dir=' + process.cwd());
127
129
  argv.push('-Dnode_engine=' + (gyp.opts.node_engine || process.jsEngine || 'v8'));
128
130
  argv.push('--depth=.'), argv.push('--no-parallel');
129
131
  argv.push('--generator-output', outputDir); // 告诉 gyp 把 Makefile/Solution 文件写到 output_dir
130
- // 使用 find-visualstudio 探测到的实际 toolset(v140/v141/v142/v143/v145...),
131
- // 不再硬编码,以兼容 VS2013+ 各版本
132
+ // 使用 find-visualstudio 探测到的实际 toolset(v140/v141/v142/v143/v145...),
133
+ // 不再硬编码,以兼容 VS2013+ 各版本
132
134
  if (win) {
133
135
  if (vsInfo?.toolset) argv.push('-Gmsvs_toolset=' + vsInfo.toolset);
134
- else log.warn('gyp', '未能探测到 VS toolset,将使用 gyp 默认值');
136
+ else log.warn('gyp', '未能探测到 VS toolset,将使用 gyp 默认值');
135
137
  }
136
138
 
137
139
  argv.push('-Goutput_dir=.'); // 告诉 make 把输出写到同一目录
@@ -187,21 +189,22 @@ const configure = async (gyp, argv) => {
187
189
  process.env.PYTHON = python;
188
190
 
189
191
  if (gyp.opts.nodedir) {
190
- // 指定了 --nodedir,用它作为开发文件目录
192
+ // 指定了 --nodedir,用它作为开发文件目录
191
193
  nodeDir = gyp.opts.nodedir.replace(/^~/, os.homedir());
192
194
  log.verbose('get node dir', 'compiling against specified --nodedir dev files: %s', nodeDir);
193
195
  } else {
194
- // 未指定 --nodedir,先确保 Node 依赖已安装
196
+ // 未指定 --nodedir,先确保 Node 依赖已安装
195
197
  if ('v' + release.version !== process.version) {
196
- // 指定了 --target,确定目标版本
198
+ // 指定了 --target,确定目标版本
197
199
  log.verbose('get node dir', 'compiling against --target node version: %s', release.version);
198
200
  } else {
199
- // 未指定 --target,使用当前主机 Node 版本
200
- log.verbose('get node dir', 'no --target version specified, falling back to host node version: %s', release.version);
201
+ // 未指定 --target,使用当前主机 Node 版本
202
+ log.verbose('get node dir',
203
+ 'no --target version specified, falling back to host node version: %s', release.version);
201
204
  }
202
205
 
203
206
  if (!release.semver) throw new Error('版本号无效: ' + release.version); // 无法用 semver 解析版本字符串
204
- // 如果指定了 tarball 选项,总是删除并重装 headers 到 devdir,
207
+ // 如果指定了 tarball 选项,总是删除并重装 headers 到 devdir,
205
208
  // 否则只在不存在时安装
206
209
  gyp.opts.ensure = !gyp.opts.tarball, await gyp.commands.install([release.version]);
207
210
  log.verbose('get node dir', 'target node version installed:', release.versionDir);
@@ -16,7 +16,7 @@ const fs = gracefulFs.promises,
16
16
  * 读取基础 config.gypi
17
17
  */
18
18
  getBaseConfigGypi = async ({ gyp, nodeDir }) => {
19
- // 在以下情况优先读取 $nodeDir/include/node/config.gypi:
19
+ // 在以下情况优先读取 $nodeDir/include/node/config.gypi:
20
20
  // 1. 指定了 --dist-url 或 --nodedir
21
21
  // 2. 且没有指定 --force-process-config
22
22
  const useCustomHeaders = gyp.opts.nodedir || gyp.opts.disturl || gyp.opts['dist-url'],
@@ -40,8 +40,8 @@ const fs = gracefulFs.promises,
40
40
  if (!config.variables) config.variables = {};
41
41
 
42
42
  const defaults = config.target_defaults, variables = config.variables;
43
- // 不要继承 base config.gypi 的 defaults,
44
- // 否则当 node 可执行文件在另一台机器编译(lib/include 路径不同)时会出问题
43
+ // 不要继承 base config.gypi 的 defaults,
44
+ // 否则当 node 可执行文件在另一台机器编译(lib/include 路径不同)时会出问题
45
45
  defaults.cflags = [], defaults.defines = [], defaults.include_dirs = [], defaults.libraries = [];
46
46
 
47
47
  // 设置 default_configuration
@@ -66,14 +66,14 @@ const fs = gracefulFs.promises,
66
66
  else log.warn('仅 Visual Studio 2017 15.9 及以上版本支持编译 ARM64 汇编');
67
67
  }
68
68
  variables.msbuild_path = vsInfo.msBuild;
69
- // Windows 原生构建走 MSVC 工具集:必须关闭 clang 与 LTO,
70
- // 否则 common.gypi 会把 toolset 设为 ClangCL,并向 MSVC 链接器传入 Clang 专用参数
71
- // (-flto=thin、/opt:lldltojobs),导致 MSB8020 或 LNK1117
69
+ // Windows 原生构建走 MSVC 工具集:必须关闭 clang 与 LTO,
70
+ // 否则 common.gypi 会把 toolset 设为 ClangCL,并向 MSVC 链接器传入 Clang 专用参数
71
+ // (-flto=thin、/opt:lldltojobs),导致 MSB8020 或 LNK1117
72
72
  if (!gyp.opts.format || gyp.opts.format === 'msvs')
73
73
  variables.clang = 0, variables.enable_lto = 'false', variables.enable_thin_lto = 'false', variables.lto_jobs = '';
74
74
  }
75
75
 
76
- // 把其余未知选项当作变量写入,支持模块自定义 configure 参数,例如:
76
+ // 把其余未知选项当作变量写入,支持模块自定义 configure 参数,例如:
77
77
  // $ node-gyp configure --shared-libxml2
78
78
  for (const [k, v] of Object.entries(gyp.opts)) {
79
79
  if (k === 'argv' || k in gyp.configDefs) continue;
@@ -106,4 +106,4 @@ const fs = gracefulFs.promises,
106
106
  return configPath;
107
107
  };
108
108
 
109
- export { createConfigGypi, parseConfigGypi, getCurrentConfigGypi }
109
+ export { createConfigGypi, parseConfigGypi, getCurrentConfigGypi }
package/lib/download.js CHANGED
@@ -4,10 +4,10 @@ import * as log from './log.js';
4
4
 
5
5
  const { promises: fs } = gracefulFs,
6
6
  /**
7
- * 读取 CA 证书文件,按证书边界切分为多个证书
7
+ * 读取 CA 证书文件,按证书边界切分为多个证书
8
8
  */
9
9
  readCAFile = async filename => {
10
- // CA 文件可能包含多份证书,按证书边界切分; [\S\s]*? 用于匹配包括换行在内的所有内容;
10
+ // CA 文件可能包含多份证书,按证书边界切分; [\S\s]*? 用于匹配包括换行在内的所有内容;
11
11
  const ca = await fs.readFile(filename, 'utf8'), re = /(-----BEGIN CERTIFICATE-----[\S\s]*?-----END CERTIFICATE-----)/g;
12
12
  return ca.match(re);
13
13
  },
@@ -28,4 +28,4 @@ const { promises: fs } = gracefulFs,
28
28
  return res;
29
29
  }
30
30
 
31
- export { readCAFile, download }
31
+ export { readCAFile, download }
@@ -7,33 +7,33 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)),
7
7
  * 从脚本位置或进程对象推断 Node 根目录
8
8
  */
9
9
  findNodeDirectory = (scriptLocation, processObj) => {
10
- // 未传入时使用默认值,便于回归测试
10
+ // 未传入时使用默认值,便于回归测试
11
11
  if (scriptLocation === undefined) scriptLocation = __dirname;
12
12
  if (processObj === undefined) processObj = process;
13
13
 
14
- // 看看上层目录结构,判断当前所处位置
14
+ // 看看上层目录结构,判断当前所处位置
15
15
  const npmParentDirectory = path.join(scriptLocation, '../../../..');
16
16
  log.verbose('node-gyp root', 'npm_parent_directory is ' + path.basename(npmParentDirectory));
17
17
  log.verbose('node-gyp root', 'Finding node root directory');
18
18
  let nodeRootDir = '';
19
19
  if (path.basename(npmParentDirectory) === 'deps') {
20
- // 处于构建目录中,脚本位于 deps/npm/node_modules/node-gyp/lib
20
+ // 处于构建目录中,脚本位于 deps/npm/node_modules/node-gyp/lib
21
21
  nodeRootDir = path.join(npmParentDirectory, '..');
22
22
  log.verbose('node-gyp root', 'in build directory, root = ' + nodeRootDir);
23
23
  } else if (path.basename(npmParentDirectory) === 'node_modules') {
24
- // 处于 Node 安装目录中,脚本位于
24
+ // 处于 Node 安装目录中,脚本位于
25
25
  // lib/node_modules/npm/node_modules/node-gyp/lib 或
26
- // node_modules/npm/node_modules/node-gyp/lib(视平台而定)
26
+ // node_modules/npm/node_modules/node-gyp/lib(视平台而定)
27
27
  if (processObj.platform === 'win32') nodeRootDir = path.join(npmParentDirectory, '..');
28
28
  else nodeRootDir = path.join(npmParentDirectory, '../..');
29
29
  log.verbose('node-gyp root', 'in install directory, root = ' + nodeRootDir);
30
30
  } else {
31
- // 无法判断,尝试从 node 可执行文件的位置推断
31
+ // 无法判断,尝试从 node 可执行文件的位置推断
32
32
  const nodeDir = path.dirname(processObj.execPath), directoryUp = path.basename(nodeDir);
33
33
  if (directoryUp === 'bin') nodeRootDir = path.join(nodeDir, '..');
34
34
  else if (directoryUp === 'Release' || directoryUp === 'Debug') {
35
- // 如果是刚构建的 node,且目录结构为仓库结构:
36
- // Windows 只需上一层,其余平台两层
35
+ // 如果是刚构建的 node,且目录结构为仓库结构:
36
+ // Windows 只需上一层,其余平台两层
37
37
  if (processObj.platform === 'win32') nodeRootDir = path.join(nodeDir, '..');
38
38
  else nodeRootDir = path.join(nodeDir, '../..');
39
39
  }
@@ -42,4 +42,4 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)),
42
42
  return nodeRootDir;
43
43
  }
44
44
 
45
- export { findNodeDirectory }
45
+ export { findNodeDirectory }
@@ -6,7 +6,7 @@ import fs from 'fs';
6
6
 
7
7
  const win = process.platform === 'win32',
8
8
  /**
9
- * 获取当前操作系统用户名(失败时返回 undefined)
9
+ * 获取当前操作系统用户名(失败时返回 undefined)
10
10
  */
11
11
  getOsUserInfo = () => {
12
12
  try { return os.userInfo().username } catch { }
@@ -19,8 +19,8 @@ const win = process.platform === 'win32',
19
19
  programFilesX86 = process.env['ProgramFiles(x86)'] || `${programFiles} (x86)`,
20
20
  systemRoot = process.env.SystemRoot || `${systemDrive}\\Windows`,
21
21
  /**
22
- * 动态扫描 Windows 上所有已安装的 Python,不硬编码版本号。
23
- * 官方安装器目录命名:3.14 -> Python314,3.9 -> Python39,32 位加 -32 后缀。
22
+ * 动态扫描 Windows 上所有已安装的 Python,不硬编码版本号;
23
+ * 官方安装器目录命名:3.14 -> Python314,3.9 -> Python39,32 位加 -32 后缀;
24
24
  */
25
25
  scanWindowsPythonLocations = () => {
26
26
  const results = [], bases = [foundLocalAppData ? `${localAppData}\\Programs\\Python` : null, `${programFiles}\\Python`,
@@ -40,13 +40,13 @@ const win = process.platform === 'win32',
40
40
  return results;
41
41
  },
42
42
  /**
43
- * py.exe 启动器候选:先试 PATH 中的,再试常见绝对路径,
44
- * 避免 Gradle / CI 环境下 PATH 不含 C:\Windows 的情况。
43
+ * py.exe 启动器候选:先试 PATH 中的,再试常见绝对路径,
44
+ * 避免 Gradle / CI 环境下 PATH 不含 C:\Windows 的情况;
45
45
  */
46
46
  pyLauncherCandidates = win ? ['py.exe', `${systemRoot}\\py.exe`, `${systemRoot}\\System32\\py.exe`] : [];
47
47
 
48
48
  /**
49
- * Python 查找器:按顺序尝试多种途径定位可用的 Python 3.6+
49
+ * Python 查找器:按顺序尝试多种途径定位可用的 Python 3.6+
50
50
  */
51
51
  class PythonFinder {
52
52
  static findPython = (...args) => new PythonFinder(...args).findPython();
@@ -66,12 +66,12 @@ class PythonFinder {
66
66
  this.configPython = configPython, this.errorLog = [];
67
67
  }
68
68
 
69
- // 以 verbose 级别记录日志,同时保存下来,出错时以 error 级别展示,便于诊断
69
+ // 以 verbose 级别记录日志,同时保存下来,出错时以 error 级别展示,便于诊断
70
70
  addLog(message) {
71
71
  this.log.verbose(message), this.errorLog.push(message);
72
72
  }
73
73
 
74
- // 依次尝试多种 Python 定位方式。忽略错误,直到找到可用版本
74
+ // 依次尝试多种 Python 定位方式;忽略错误,直到找到可用版本
75
75
  async findPython() {
76
76
  const SKIP = 0, FAIL = 1,
77
77
  toCheck = (() => {
@@ -158,7 +158,7 @@ class PythonFinder {
158
158
  return this.fail();
159
159
  }
160
160
 
161
- // 检查命令是否为可用的 Python。
161
+ // 检查命令是否为可用的 Python;
162
162
  async checkCommand(command) {
163
163
  this.log.verbose(`- executing "${command}" to get executable path`);
164
164
  try {
@@ -171,7 +171,7 @@ class PythonFinder {
171
171
  }
172
172
  }
173
173
 
174
- // 检查指定 py 启动器是否能找到 Python 3。
174
+ // 检查指定 py 启动器是否能找到 Python 3;
175
175
  async checkPyLauncher(launcher = this.pyLauncher) {
176
176
  this.log.verbose(`- executing "${launcher}" to get Python 3 executable path`);
177
177
  try {
@@ -184,7 +184,7 @@ class PythonFinder {
184
184
  }
185
185
  }
186
186
 
187
- // 通过 "py -0p" 枚举所有已注册的 Python,覆盖非标准安装位置。
187
+ // 通过 "py -0p" 枚举所有已注册的 Python,覆盖非标准安装位置;
188
188
  async checkPyList() {
189
189
  this.log.verbose('- executing "py -0p" to list registered Pythons');
190
190
  let lastErr;
@@ -213,7 +213,7 @@ class PythonFinder {
213
213
  throw lastErr || new Error('py -0p returned no usable Python');
214
214
  }
215
215
 
216
- // 检查某个 Python 可执行文件版本是否可用。
216
+ // 检查某个 Python 可执行文件版本是否可用;
217
217
  async checkExecPath(execPath) {
218
218
  this.log.verbose(`- executing "${execPath}" to get version`);
219
219
  try {
@@ -242,8 +242,8 @@ class PythonFinder {
242
242
  }
243
243
  }
244
244
 
245
- // 执行外部命令。execFile 包装不 reject,通过 [err, stdout, stderr] 返回结果,
246
- // 必须显式检查 err,否则失败会被当成"成功但空输出",掩盖真实原因。
245
+ // 执行外部命令;execFile 包装不 reject,通过 [err, stdout, stderr] 返回结果,
246
+ // 必须显式检查 err,否则失败会被当成"成功但空输出",掩盖真实原因;
247
247
  async run(exec, args, shell) {
248
248
  const env = Object.assign({}, this.env), opts = { env, shell };
249
249
  env.TERM = 'dumb';
@@ -6,7 +6,7 @@ import { regSearchKeys, execFile } from './util.js';
6
6
 
7
7
  const path = nodePath.win32, __dirname = nodePath.dirname(fileURLToPath(import.meta.url));
8
8
  /**
9
- * Visual Studio 查找器:定位可用的 VS 安装
9
+ * Visual Studio 查找器:定位可用的 VS 安装
10
10
  */
11
11
  class VisualStudioFinder {
12
12
  static findVisualStudio = (...args) => new VisualStudioFinder(...args).findVisualStudio();
@@ -17,7 +17,7 @@ class VisualStudioFinder {
17
17
  this.nodeSemver = nodeSemver, this.configMsvsVersion = configMsvsVersion, this.errorLog = [], this.validVersions = [];
18
18
  }
19
19
 
20
- // 以 verbose 级别记录日志,同时保存下来,出错时以 error 级别展示,便于诊断
20
+ // 以 verbose 级别记录日志,同时保存下来,出错时以 error 级别展示,便于诊断
21
21
  addLog(message) {
22
22
  this.log.verbose(message), this.errorLog.push(message);
23
23
  }
@@ -66,7 +66,7 @@ class VisualStudioFinder {
66
66
  this.errorLog.push(
67
67
  'msvs_version does not match this VS Command Prompt or the', 'installation cannot be used.');
68
68
  else if (this.configMsvsVersion) {
69
- // 指定了 msvs_version 但没找到 VS,输出可接受的版本
69
+ // 指定了 msvs_version 但没找到 VS,输出可接受的版本
70
70
  this.errorLog.push('');
71
71
  if (this.validVersions) {
72
72
  this.errorLog.push('valid versions for msvs_version:');
@@ -76,7 +76,7 @@ class VisualStudioFinder {
76
76
  }
77
77
 
78
78
  const errorLog = this.errorLog.join('\n'),
79
- // Windows 80 列控制台,用到 X 标记列之前(含日志前缀共 79 字符,可用 62 字符):
79
+ // Windows 80 列控制台,用到 X 标记列之前(含日志前缀共 79 字符,可用 62 字符):
80
80
  infoLog = [
81
81
  '**************************************************************',
82
82
  'You need to install the latest version of Visual Studio',
@@ -90,7 +90,7 @@ class VisualStudioFinder {
90
90
  throw new Error('未找到可用的 Visual Studio 安装');
91
91
  }
92
92
 
93
- // 调用 PowerShell 脚本,获取 Visual Studio 2017 或更新版本的信息
93
+ // 调用 PowerShell 脚本,获取 Visual Studio 2017 或更新版本的信息
94
94
  async findVisualStudio2017OrNewer() {
95
95
  const ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe'),
96
96
  csFile = path.join(__dirname, 'Find-VisualStudio.cs'),
@@ -102,7 +102,7 @@ class VisualStudioFinder {
102
102
  return this.parseData(err, stdout, stderr);
103
103
  }
104
104
 
105
- // 解析 PowerShell 脚本输出,寻找可用的 Visual Studio 2017 或更新版本
105
+ // 解析 PowerShell 脚本输出,寻找可用的 Visual Studio 2017 或更新版本
106
106
  parseData(err, stdout, stderr) {
107
107
  this.log.silly('PS stderr = %j', stderr)
108
108
 
@@ -149,7 +149,7 @@ class VisualStudioFinder {
149
149
  return false;
150
150
  })
151
151
 
152
- // 排序:新版本在前
152
+ // 排序:新版本在前
153
153
  vsInfo.sort((a, b) => b.versionYear - a.versionYear)
154
154
 
155
155
  for (let i = 0; i < vsInfo.length; ++i) {
@@ -182,7 +182,7 @@ class VisualStudioFinder {
182
182
  return null;
183
183
  }
184
184
 
185
- // 辅助:解析版本信息
185
+ // 辅助:解析版本信息
186
186
  getVersionInfo(info) {
187
187
  const match = /^(\d+)\.(\d+)\./.exec(info.version);
188
188
  if (!match) {
@@ -206,7 +206,7 @@ class VisualStudioFinder {
206
206
  return existsSync(path);
207
207
  }
208
208
 
209
- // 辅助:解析 MSBuild 信息
209
+ // 辅助:解析 MSBuild 信息
210
210
  getMSBuild(info, versionYear) {
211
211
  const pkg = 'Microsoft.VisualStudio.VC.MSBuild.Base',
212
212
  msbuildPath = path.join(info.path, 'MSBuild', 'Current', 'Bin', 'MSBuild.exe'),
@@ -217,16 +217,16 @@ class VisualStudioFinder {
217
217
  if (versionYear === 2019) return msbuildPath;
218
218
  }
219
219
  /**
220
- * Visual Studio 2022 没有 MSBuild 包。
221
- * ARM64 上编译的支持从 MSVC 14.32.31326 起加入,
222
- * 因此用户设备是 ARM64 时优先使用它。
220
+ * Visual Studio 2022 没有 MSBuild 包;
221
+ * ARM64 上编译的支持从 MSVC 14.32.31326 起加入,
222
+ * 因此用户设备是 ARM64 时优先使用它;
223
223
  */
224
224
  if (process.arch === 'arm64' && this.msBuildPathExists(msbuildPathArm64)) return msbuildPathArm64;
225
225
  else if (this.msBuildPathExists(msbuildPath)) return msbuildPath;
226
226
  return null;
227
227
  }
228
228
 
229
- // 辅助:解析 toolset 信息
229
+ // 辅助:解析 toolset 信息
230
230
  getToolset(info, versionYear) {
231
231
  const pkg = 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', express = 'Microsoft.VisualStudio.WDExpress';
232
232
  if (info.packages.indexOf(pkg) !== -1) this.log.silly('- found VC.Tools.x86.x64');
@@ -241,7 +241,7 @@ class VisualStudioFinder {
241
241
  return null;
242
242
  }
243
243
 
244
- // 辅助:解析 Windows SDK 信息
244
+ // 辅助:解析 Windows SDK 信息
245
245
  getSDK(info) {
246
246
  const win8SDK = 'Microsoft.VisualStudio.Component.Windows81SDK',
247
247
  win10SDKPrefix = 'Microsoft.VisualStudio.Component.Windows10SDK.',
@@ -291,7 +291,7 @@ class VisualStudioFinder {
291
291
  return this.findOldVS({ version: '12.0', versionMajor: 12, versionMinor: 0, versionYear: 2013, toolset: 'v120' });
292
292
  }
293
293
 
294
- // 辅助:VS2013 和 VS2015 的公共代码
294
+ // 辅助:VS2013 和 VS2015 的公共代码
295
295
  async findOldVS(info) {
296
296
  const regVC7 = ['HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7',
297
297
  'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7'],
@@ -322,10 +322,10 @@ class VisualStudioFinder {
322
322
  }
323
323
  }
324
324
 
325
- // 找到可用的 Visual Studio 后:
326
- // - 把它加入 validVersions,用于在指定版本未找到时输出;
327
- // - 检查是否是请求的版本;
328
- // - 检查是否匹配 Visual Studio 命令提示符。
325
+ // 找到可用的 Visual Studio 后:
326
+ // - 把它加入 validVersions,用于在指定版本未找到时输出;
327
+ // - 检查是否是请求的版本;
328
+ // - 检查是否匹配 Visual Studio 命令提示符;
329
329
  checkConfigVersion(versionYear, vsPath) {
330
330
  this.validVersions.push(versionYear), this.validVersions.push(vsPath);
331
331