@flun/nodejs-mobile-gyp 1.0.1
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.
- package/CHANGELOG.md +36 -0
- package/LICENSE +29 -0
- package/README.md +252 -0
- package/addon.gypi +209 -0
- package/bin/node-gyp.js +144 -0
- package/gyp/LICENSE +28 -0
- package/gyp/README.md +30 -0
- package/gyp/data/win/large-pdb-shim.cc +12 -0
- package/gyp/gyp +8 -0
- package/gyp/gyp.bat +5 -0
- package/gyp/gyp_main.py +45 -0
- package/gyp/pylib/gyp/MSVSNew.py +365 -0
- package/gyp/pylib/gyp/MSVSProject.py +206 -0
- package/gyp/pylib/gyp/MSVSSettings.py +1270 -0
- package/gyp/pylib/gyp/MSVSToolFile.py +59 -0
- package/gyp/pylib/gyp/MSVSUserFile.py +153 -0
- package/gyp/pylib/gyp/MSVSUtil.py +271 -0
- package/gyp/pylib/gyp/MSVSVersion.py +574 -0
- package/gyp/pylib/gyp/__init__.py +692 -0
- package/gyp/pylib/gyp/common.py +654 -0
- package/gyp/pylib/gyp/easy_xml.py +169 -0
- package/gyp/pylib/gyp/flock_tool.py +55 -0
- package/gyp/pylib/gyp/generator/__init__.py +0 -0
- package/gyp/pylib/gyp/generator/analyzer.py +804 -0
- package/gyp/pylib/gyp/generator/android.py +1173 -0
- package/gyp/pylib/gyp/generator/cmake.py +1318 -0
- package/gyp/pylib/gyp/generator/compile_commands_json.py +123 -0
- package/gyp/pylib/gyp/generator/dump_dependency_json.py +103 -0
- package/gyp/pylib/gyp/generator/eclipse.py +461 -0
- package/gyp/pylib/gyp/generator/gypd.py +89 -0
- package/gyp/pylib/gyp/generator/gypsh.py +58 -0
- package/gyp/pylib/gyp/generator/make.py +2710 -0
- package/gyp/pylib/gyp/generator/msvs.py +3981 -0
- package/gyp/pylib/gyp/generator/ninja.py +2933 -0
- package/gyp/pylib/gyp/generator/xcode.py +1397 -0
- package/gyp/pylib/gyp/input.py +3115 -0
- package/gyp/pylib/gyp/mac_tool.py +771 -0
- package/gyp/pylib/gyp/msvs_emulation.py +1262 -0
- package/gyp/pylib/gyp/ninja_syntax.py +174 -0
- package/gyp/pylib/gyp/simple_copy.py +61 -0
- package/gyp/pylib/gyp/win_tool.py +373 -0
- package/gyp/pylib/gyp/xcode_emulation.py +1935 -0
- package/gyp/pylib/gyp/xcode_ninja.py +302 -0
- package/gyp/pylib/gyp/xcodeproj_file.py +3198 -0
- package/gyp/pylib/gyp/xml_fix.py +65 -0
- package/gyp/pylib/packaging/LICENSE +3 -0
- package/gyp/pylib/packaging/LICENSE.APACHE +177 -0
- package/gyp/pylib/packaging/LICENSE.BSD +23 -0
- package/gyp/pylib/packaging/__init__.py +15 -0
- package/gyp/pylib/packaging/_elffile.py +108 -0
- package/gyp/pylib/packaging/_manylinux.py +252 -0
- package/gyp/pylib/packaging/_musllinux.py +83 -0
- package/gyp/pylib/packaging/_parser.py +359 -0
- package/gyp/pylib/packaging/_structures.py +61 -0
- package/gyp/pylib/packaging/_tokenizer.py +192 -0
- package/gyp/pylib/packaging/markers.py +252 -0
- package/gyp/pylib/packaging/metadata.py +825 -0
- package/gyp/pylib/packaging/py.typed +0 -0
- package/gyp/pylib/packaging/requirements.py +90 -0
- package/gyp/pylib/packaging/specifiers.py +1030 -0
- package/gyp/pylib/packaging/tags.py +553 -0
- package/gyp/pylib/packaging/utils.py +172 -0
- package/gyp/pylib/packaging/version.py +563 -0
- package/lib/Find-VisualStudio.cs +250 -0
- package/lib/build.js +221 -0
- package/lib/clean.js +19 -0
- package/lib/configure.js +295 -0
- package/lib/create-config-gypi.js +163 -0
- package/lib/download.js +44 -0
- package/lib/find-node-directory.js +62 -0
- package/lib/find-python.js +303 -0
- package/lib/find-visualstudio.js +448 -0
- package/lib/install.js +419 -0
- package/lib/list.js +30 -0
- package/lib/log.js +174 -0
- package/lib/node-gyp.js +201 -0
- package/lib/process-release.js +144 -0
- package/lib/rebuild.js +14 -0
- package/lib/remove.js +47 -0
- package/lib/util.js +83 -0
- package/package.json +72 -0
- package/src/win_delay_load_hook.cc +39 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.1] - 2026-09-21
|
|
4
|
+
|
|
5
|
+
### 首发
|
|
6
|
+
|
|
7
|
+
- 发布 `@flun/nodejs-mobile-gyp`,基于 [nodejs-mobile-gyp](https://github.com/janeasystems/nodejs-mobile-gyp) 0.4.0 与上游 [node-gyp](https://github.com/nodejs/node-gyp) fork
|
|
8
|
+
- 用于为 nodejs-mobile 环境编译原生模块(Android / iOS)
|
|
9
|
+
|
|
10
|
+
### 代码风格
|
|
11
|
+
|
|
12
|
+
- 全量改造为 **ESM**(`package.json` 的 `type: "module"`)
|
|
13
|
+
- 导出方式统一为文件末尾 `export { ... }`
|
|
14
|
+
- 函数声明改为 `const xxx = (...) => {}`(`class` 保留)
|
|
15
|
+
- 注释全部中文化
|
|
16
|
+
|
|
17
|
+
### Windows 适配
|
|
18
|
+
|
|
19
|
+
- 支持 **Visual Studio 2026**(版本号 18,`versionYear=2026`,toolset `v145`)
|
|
20
|
+
- 强制走 **MSVC** 工具集,不再使用 ClangCL
|
|
21
|
+
- 关闭 **LTO**:`enable_lto` / `enable_thin_lto` 置 `false`,`lto_jobs` 置空
|
|
22
|
+
- 避免 `MSB8020: 无法找到 ClangCL 的生成工具`
|
|
23
|
+
- 避免 `LNK1117: 选项"opt:lldltojobs=2"中的语法错误`
|
|
24
|
+
- `configure` 阶段显式追加 `-Gmsvs_toolset=v145`
|
|
25
|
+
|
|
26
|
+
### 依赖升级
|
|
27
|
+
|
|
28
|
+
- `tar`: `^6.1.2` → `^7.5.21`
|
|
29
|
+
- `glob`: `^10.3.10` → `^13.0.6`
|
|
30
|
+
- `make-fetch-happen`: `^13.0.0` → `^16.0.1`
|
|
31
|
+
- 连带消除 `inflight`、`rimraf@3`、旧版 `glob` 等停更依赖
|
|
32
|
+
|
|
33
|
+
### 验证
|
|
34
|
+
|
|
35
|
+
- Windows + VS2026 BuildTools + Python 3.14 + Node 26.8.1 环境下,`configure` + `build` 全流程通过
|
|
36
|
+
- 生成的 `.node` 能被 Node 正常加载
|
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
ISC 许可证 (ISC License)
|
|
2
|
+
|
|
3
|
+
版权所有 (c) 2026, flun <open@flun.top>
|
|
4
|
+
|
|
5
|
+
特此免费授予任何获得本软件及相关文档文件(“软件”)副本的人,不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件副本的权利,并允许向其提供本软件的人这样做,但须满足以下条件:
|
|
6
|
+
|
|
7
|
+
上述版权声明和本许可声明应包含在本软件的所有副本或重要部分中;
|
|
8
|
+
|
|
9
|
+
本软件按“原样”提供,不作任何形式的明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证;在任何情况下,作者或版权持有人均不对因本软件或本软件的使用或其他交易而产生的任何索赔、损害或其他责任负责,无论是合同之诉、侵权之诉还是其他行为之诉;
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
英文原文 (English Version)
|
|
14
|
+
|
|
15
|
+
ISC License
|
|
16
|
+
|
|
17
|
+
Copyright (c) 2026, flun <open@flun.top>
|
|
18
|
+
|
|
19
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
20
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
21
|
+
copyright notice and this permission notice appear in all copies.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
24
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
25
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
26
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
27
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
28
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
29
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# @flun/nodejs-mobile-gyp
|
|
2
|
+
|
|
3
|
+
移动端 Node.js 原生模块(Native Addon)的交叉编译工具。
|
|
4
|
+
|
|
5
|
+
用于为 [nodejs-mobile](https://github.com/nodejs-mobile/nodejs-mobile) 环境编译 C/C++ 原生模块,支持 Android 与 iOS 的交叉编译。
|
|
6
|
+
|
|
7
|
+
[`@flun/nodejs-mobile-react-native`](https://www.npmjs.com/package/@flun/nodejs-mobile-react-native) 在构建时会自动调用本包,无需手动安装。
|
|
8
|
+
|
|
9
|
+
本包是 [`nodejs-mobile-gyp`](https://github.com/nodejs-mobile/nodejs-mobile-gyp) 的 flun fork,后者又基于上游 [`node-gyp`](https://github.com/nodejs/node-gyp)。
|
|
10
|
+
|
|
11
|
+
- GitHub:https://github.com/OpenFlun/nodejs-mobile-gyp
|
|
12
|
+
- gitee: https://gitee.com/OpenFlun/nodejs-mobile-gyp
|
|
13
|
+
- npm:https://www.npmjs.com/package/@flun/nodejs-mobile-gyp
|
|
14
|
+
|
|
15
|
+
## 项目结构
|
|
16
|
+
|
|
17
|
+
```txt
|
|
18
|
+
@flun/nodejs-mobile-gyp/
|
|
19
|
+
│
|
|
20
|
+
├── bin/
|
|
21
|
+
│ └── node-gyp.js # CLI 入口(#!/usr/bin/env node),创建 Gyp 实例并依次执行命令队列
|
|
22
|
+
│
|
|
23
|
+
├── lib/ # 核心实现,全部为 ESM
|
|
24
|
+
│ ├── node-gyp.js # Gyp 主类:参数解析、命令分发、usage 生成
|
|
25
|
+
│ ├── build.js # build 命令:调用 make / msbuild 编译原生模块
|
|
26
|
+
│ ├── clean.js # clean 命令:删除 build 目录
|
|
27
|
+
│ ├── configure.js # configure 命令:下载 headers、生成 config.gypi 与工程文件
|
|
28
|
+
│ ├── rebuild.js # rebuild 命令:依次执行 clean + configure + build
|
|
29
|
+
│ ├── install.js # install 命令:下载并解压指定版本的 Node 开发文件
|
|
30
|
+
│ ├── remove.js # remove 命令:删除指定版本的 Node 开发文件
|
|
31
|
+
│ ├── list.js # list 命令:列出已安装的 Node 开发文件版本
|
|
32
|
+
│ ├── create-config-gypi.js # 生成 config.gypi;Windows 上强制 MSVC 工具集、关闭 LTO
|
|
33
|
+
│ ├── process-release.js # 解析下载 URL、本地目录名、headers 与 node.lib 地址
|
|
34
|
+
│ ├── download.js # 基于 make-fetch-happen 的 HTTP 下载与 CA 读取
|
|
35
|
+
│ ├── find-node-directory.js # 推断 Node 安装根目录(用于 AIX / zOS)
|
|
36
|
+
│ ├── find-python.js # PythonFinder 类:按顺序定位可用的 Python 3.6+
|
|
37
|
+
│ ├── find-visualstudio.js # VisualStudioFinder 类:定位可用的 VS 安装(含 VS2026)
|
|
38
|
+
│ ├── Find-VisualStudio.cs # PowerShell 调用的 C# 脚本,枚举 VS 安装信息
|
|
39
|
+
│ ├── log.js # Logger 类 + proc-log 包装,分级着色日志
|
|
40
|
+
│ └── util.js # 通用工具:execFile 包装、注册表读取、候选文件查找
|
|
41
|
+
│
|
|
42
|
+
├── gyp/ # 内置的 gyp 工具(Python)
|
|
43
|
+
│ ├── gyp # Python 启动脚本(Unix)
|
|
44
|
+
│ ├── gyp.bat # Python 启动脚本(Windows)
|
|
45
|
+
│ ├── gyp_main.py # gyp 主入口
|
|
46
|
+
│ ├── LICENSE # gyp 自身的许可证
|
|
47
|
+
│ ├── pylib/gyp/ # gyp 核心 Python 模块
|
|
48
|
+
│ │ ├── input.py # 解析 .gyp / .gypi 文件
|
|
49
|
+
│ │ ├── common.py # 通用工具
|
|
50
|
+
│ │ ├── MSVS*.py # MSBuild / VS 工程生成
|
|
51
|
+
│ │ ├── msvs_emulation.py # VS 配置模拟
|
|
52
|
+
│ │ ├── xcode*.py # Xcode 工程生成
|
|
53
|
+
│ │ ├── mac_tool.py # macOS 工具链
|
|
54
|
+
│ │ ├── win_tool.py # Windows 工具链
|
|
55
|
+
│ │ └── generator/ # 各类生成器后端(make / msvs / ninja / xcode / cmake ...)
|
|
56
|
+
│ ├── pylib/packaging/ # gyp 依赖的 Python packaging 库(vendored)
|
|
57
|
+
│ └── data/win/
|
|
58
|
+
│ └── large-pdb-shim.cc # Windows 大 PDB 兼容编译单元
|
|
59
|
+
│
|
|
60
|
+
├── src/
|
|
61
|
+
│ └── win_delay_load_hook.cc # Windows 加载延迟钩子(编译进每个原生模块)
|
|
62
|
+
│
|
|
63
|
+
├── addon.gypi # 所有原生模块共用的 gyp 配置
|
|
64
|
+
├── package.json # type: module,bin 指向 bin/node-gyp.js
|
|
65
|
+
├── LICENSE # 本包许可证(ISC)
|
|
66
|
+
├── README.md # 本文件
|
|
67
|
+
├── CHANGELOG.md # 版本变更记录
|
|
68
|
+
├── .gitignore # Git 忽略规则
|
|
69
|
+
├── .npmignore # npm 发布排除规则
|
|
70
|
+
├── .gitattributes # Git 换行符 / 二进制标记
|
|
71
|
+
└── macOS_Catalina_acid_test.sh # macOS Catalina 兼容性验证脚本(仅本地开发,不随包发布)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 本 fork 的改动
|
|
75
|
+
|
|
76
|
+
本 fork 在功能上与原版 `nodejs-mobile-gyp` 一致,做了以下改造。
|
|
77
|
+
|
|
78
|
+
### 代码风格
|
|
79
|
+
|
|
80
|
+
| 项 | 原版 | 本 fork |
|
|
81
|
+
| -------- | ----------------------- | --------------------------------------------- |
|
|
82
|
+
| 模块系统 | CommonJS | **ESM**(`package.json` 的 `type: "module"`) |
|
|
83
|
+
| 导出方式 | 文件内 `module.exports` | **末尾统一 `export { ... }`** |
|
|
84
|
+
| 函数声明 | `async function xxx` | `const xxx = async () =>`(`class` 保留) |
|
|
85
|
+
| 注释 | 英文 | 中文 |
|
|
86
|
+
|
|
87
|
+
### 依赖升级
|
|
88
|
+
|
|
89
|
+
| 包 | 原版 | 本 fork | 原因 |
|
|
90
|
+
| ------------------- | ---------- | --------- | -------------------------------------------- |
|
|
91
|
+
| `tar` | `^6.1.2` | `^7.5.22` | 上游 v6 停更,有安全公告 |
|
|
92
|
+
| `glob` | `^10.3.10` | `^13.0.6` | 上游 v10 停更 |
|
|
93
|
+
| `make-fetch-happen` | `^13.0.0` | `^16.0.1` | 连带升级 `cacache`,去掉 `tar@6` / `glob@10` |
|
|
94
|
+
|
|
95
|
+
升级后依赖树干净,`npm audit` 0 vulnerabilities。
|
|
96
|
+
|
|
97
|
+
### Windows 构建适配
|
|
98
|
+
|
|
99
|
+
原版在 Windows 上默认走 ClangCL 工具集,且继承 Node 官方二进制的 LTO 配置。Node.js 24+ 官方二进制由 ClangCL + ThinLTO 编译,其 `common.gypi` 会在 `clang==1` 时把 MSBuild 工具集设为 `ClangCL`,并在 `enable_lto==true` / `enable_thin_lto==true` 时向链接器传入 `-flto=thin`、`/opt:lldltojobs` 等 Clang 专用参数。若用户本机没装 ClangCL,或用的是传统 MSVC 工具链,会报以下错误:
|
|
100
|
+
|
|
101
|
+
- `MSB8020: 无法找到 ClangCL 的生成工具`
|
|
102
|
+
- `LNK1117: 选项"opt:lldltojobs=2"中的语法错误`
|
|
103
|
+
|
|
104
|
+
本 fork 强制走 MSVC 工具集并关闭 LTO,避免上述报错。
|
|
105
|
+
|
|
106
|
+
### 具体改动清单
|
|
107
|
+
|
|
108
|
+
| 文件 | 改动 |
|
|
109
|
+
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| `lib/create-config-gypi.js` | 生成 `config.gypi` 时,把 `clang` 置 0,`enable_lto` / `enable_thin_lto` 置 `'false'`,`lto_jobs` 置空。避免 `common.gypi` 把工具集改成 ClangCL、向 MSVC 传 LTO 参数 |
|
|
111
|
+
| `lib/configure.js` | 调用 gyp 时追加 `-Gmsvs_toolset=v145`,显式指定 VS2026 工具集 |
|
|
112
|
+
| `lib/find-visualstudio.js` | 支持 VS2026(版本号 18,`versionYear=2026`,toolset `v145`) |
|
|
113
|
+
|
|
114
|
+
### 迁移踩过的坑
|
|
115
|
+
|
|
116
|
+
1. **`graceful-fs` 是 CJS,命名导入会失败**
|
|
117
|
+
写成 `import gracefulFs from 'graceful-fs'`,再从 default 解构 `const { openSync, closeSync } = gracefulFs`。
|
|
118
|
+
|
|
119
|
+
2. **`tar@7` 没有 default export**
|
|
120
|
+
写成 `import * as tar from 'tar'`。
|
|
121
|
+
|
|
122
|
+
3. **`proc-log` 的解构**
|
|
123
|
+
`import procLog from 'proc-log'`,再把需要的函数从 default 里解构后统一导出。
|
|
124
|
+
|
|
125
|
+
4. **PowerShell 写文件会加 BOM**
|
|
126
|
+
`Set-Content -Encoding UTF8` 会写入 `\uFEFF`,导致 gyp 的 `eval()` 报 `SyntaxError: invalid non-printable character U+FEFF`。写 `binding.gyp` 等交给 Python eval 的文件时,用 `[System.IO.File]::WriteAllText` + `New-Object System.Text.UTF8Encoding $false`。
|
|
127
|
+
|
|
128
|
+
5. **ESM 不支持动态 `require('./' + command)`**
|
|
129
|
+
`lib/node-gyp.js` 原本用 `require('./' + command)` 动态加载命令模块,ESM 下改为在顶部静态 import 所有命令,再用静态映射表组装 `this.commands`。
|
|
130
|
+
|
|
131
|
+
6. **`__dirname` / `__filename` 在 ESM 中不存在**
|
|
132
|
+
用 `fileURLToPath(import.meta.url)` 重建。
|
|
133
|
+
|
|
134
|
+
7. **非 Windows 平台不引入 `find-visualstudio.js`**
|
|
135
|
+
该模块依赖 Windows 专属的 `path.win32` 和注册表操作,保持原版的"仅在 Windows 上条件加载"逻辑。
|
|
136
|
+
|
|
137
|
+
## 安装
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm install @flun/nodejs-mobile-gyp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
通常你不需要手动安装本包——它由 [`@flun/nodejs-mobile-react-native`](https://www.npmjs.com/package/@flun/nodejs-mobile-react-native) 在编译原生模块时自动调用。
|
|
144
|
+
|
|
145
|
+
## 使用
|
|
146
|
+
|
|
147
|
+
### 命令行
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx node-gyp <command> [options]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
或在 `package.json` 的 `scripts` 中调用:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"scripts": {
|
|
158
|
+
"build-addon": "node-gyp rebuild"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 从 Node.js 代码调用
|
|
164
|
+
|
|
165
|
+
```js
|
|
166
|
+
import createGyp from '@flun/nodejs-mobile-gyp'
|
|
167
|
+
|
|
168
|
+
const gyp = createGyp()
|
|
169
|
+
gyp.parseArgv(process.argv)
|
|
170
|
+
// gyp.todo 是待执行的命令队列
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 命令
|
|
174
|
+
|
|
175
|
+
| 命令 | 说明 |
|
|
176
|
+
| ----------- | ---------------------------------------- |
|
|
177
|
+
| `help` | 显示帮助 |
|
|
178
|
+
| `build` | 调用 `make` / `msbuild.exe` 编译原生模块 |
|
|
179
|
+
| `clean` | 删除 `build` 目录(若存在) |
|
|
180
|
+
| `configure` | 为当前平台生成工程构建文件 |
|
|
181
|
+
| `rebuild` | 依次执行 `clean` → `configure` → `build` |
|
|
182
|
+
| `install` | 为指定版本安装 Node.js 头文件 |
|
|
183
|
+
| `list` | 列出已安装的 Node.js 头文件版本 |
|
|
184
|
+
| `remove` | 删除指定版本的 Node.js 头文件 |
|
|
185
|
+
|
|
186
|
+
## 命令选项
|
|
187
|
+
|
|
188
|
+
| 选项 | 说明 |
|
|
189
|
+
| --------------------------------- | -------------------------------------------------- |
|
|
190
|
+
| `-j n`, `--jobs n` | 并行运行 `make`;`max` 表示使用所有 CPU 核心 |
|
|
191
|
+
| `--target=v6.2.1` | 目标 Node.js 版本(默认 `process.version`) |
|
|
192
|
+
| `--silly`, `--loglevel=silly` | 输出全部进度日志 |
|
|
193
|
+
| `--verbose`, `--loglevel=verbose` | 输出大部分进度日志 |
|
|
194
|
+
| `--silent`, `--loglevel=silent` | 不输出任何日志 |
|
|
195
|
+
| `debug`, `--debug` | 生成 Debug 构建(默认 Release) |
|
|
196
|
+
| `--release`, `--no-debug` | 生成 Release 构建 |
|
|
197
|
+
| `-C $dir`, `--directory=$dir` | 在指定目录运行命令 |
|
|
198
|
+
| `--make=$make` | 覆盖 `make` 命令(如 `gmake`) |
|
|
199
|
+
| `--thin=yes` | 启用 thin 静态库 |
|
|
200
|
+
| `--arch=$arch` | 目标架构(如 `ia32`) |
|
|
201
|
+
| `--tarball=$path` | 从本地 tarball 获取头文件 |
|
|
202
|
+
| `--devdir=$path` | SDK 下载目录(默认为系统缓存目录) |
|
|
203
|
+
| `--ensure` | 已存在的头文件不重装 |
|
|
204
|
+
| `--dist-url=$url` | 从自定义 URL 下载头文件 tarball |
|
|
205
|
+
| `--proxy=$url` | 下载时使用 HTTP(S) 代理 |
|
|
206
|
+
| `--noproxy=$urls` | 下载时忽略代理的 URL 列表 |
|
|
207
|
+
| `--cafile=$cafile` | 覆盖默认 CA 链(用于下载 tarball) |
|
|
208
|
+
| `--nodedir=$path` | 指定 Node 源码路径 |
|
|
209
|
+
| `--python=$path` | 指定 Python 二进制路径 |
|
|
210
|
+
| `--msvs_version=$version` | 指定 Visual Studio 版本(仅 Windows) |
|
|
211
|
+
| `--solution=$solution` | 指定 Visual Studio Solution 版本(仅 Windows) |
|
|
212
|
+
| `--force-process-config` | 强制用运行时的 `process.config` 生成 `config.gypi` |
|
|
213
|
+
|
|
214
|
+
## 配置
|
|
215
|
+
|
|
216
|
+
### 环境变量
|
|
217
|
+
|
|
218
|
+
上表中的所有命令选项,都可以用 `npm_config_OPTION_NAME` 形式的**环境变量**来设置(选项名中的 `-` 替换为 `_`)。
|
|
219
|
+
|
|
220
|
+
例如,把 `devdir` 设为 `/tmp/.gyp`:
|
|
221
|
+
|
|
222
|
+
Unix:
|
|
223
|
+
```bash
|
|
224
|
+
export npm_config_devdir=/tmp/.gyp
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Windows:
|
|
228
|
+
```console
|
|
229
|
+
set npm_config_devdir=c:\temp\.gyp
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### npm 配置(npm v9 之前)
|
|
233
|
+
|
|
234
|
+
用 `OPTION_NAME` 形式:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
npm config set [--global] devdir /tmp/.gyp
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**注意**:通过 `npm config` 设置的配置,只在 `node-gyp` **由 npm 调用时**生效,直接运行 `node-gyp` 不生效。
|
|
241
|
+
|
|
242
|
+
## 上游参考
|
|
243
|
+
|
|
244
|
+
本包是 `node-gyp` 的 fork。上游完整文档(含更多高级用法、`binding.gyp` 语法、跨平台细节)请见:
|
|
245
|
+
|
|
246
|
+
- [nodejs/node-gyp README](https://github.com/nodejs/node-gyp#readme)
|
|
247
|
+
- [gyp 用户文档](https://gyp.gsrc.io/docs/UserDocumentation.md)
|
|
248
|
+
- [gyp 输入格式参考](https://gyp.gsrc.io/docs/InputFormatReference.md)
|
|
249
|
+
|
|
250
|
+
## 许可
|
|
251
|
+
|
|
252
|
+
ISC
|
package/addon.gypi
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
{
|
|
2
|
+
'variables' : {
|
|
3
|
+
'node_engine_include_dir%': 'deps/v8/include',
|
|
4
|
+
'node_host_binary%': 'node',
|
|
5
|
+
'node_with_ltcg%': 'true',
|
|
6
|
+
},
|
|
7
|
+
'target_defaults': {
|
|
8
|
+
'type': 'loadable_module',
|
|
9
|
+
'win_delay_load_hook': 'true',
|
|
10
|
+
'product_prefix': '',
|
|
11
|
+
|
|
12
|
+
'conditions': [
|
|
13
|
+
[ 'node_engine=="chakracore"', {
|
|
14
|
+
'variables': {
|
|
15
|
+
'node_engine_include_dir%': 'deps/chakrashim/include'
|
|
16
|
+
},
|
|
17
|
+
}]
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
'include_dirs': [
|
|
21
|
+
'<(node_root_dir)/include/node',
|
|
22
|
+
'<(node_root_dir)/src',
|
|
23
|
+
'<(node_root_dir)/deps/openssl/config',
|
|
24
|
+
'<(node_root_dir)/deps/openssl/openssl/include',
|
|
25
|
+
'<(node_root_dir)/deps/uv/include',
|
|
26
|
+
'<(node_root_dir)/deps/zlib',
|
|
27
|
+
'<(node_root_dir)/<(node_engine_include_dir)'
|
|
28
|
+
],
|
|
29
|
+
'defines!': [
|
|
30
|
+
'BUILDING_UV_SHARED=1', # Inherited from common.gypi.
|
|
31
|
+
'BUILDING_V8_SHARED=1', # Inherited from common.gypi.
|
|
32
|
+
],
|
|
33
|
+
'defines': [
|
|
34
|
+
'NODE_GYP_MODULE_NAME=>(_target_name)',
|
|
35
|
+
'USING_UV_SHARED=1',
|
|
36
|
+
'USING_V8_SHARED=1',
|
|
37
|
+
# Warn when using deprecated V8 APIs.
|
|
38
|
+
'V8_DEPRECATION_WARNINGS=1'
|
|
39
|
+
],
|
|
40
|
+
|
|
41
|
+
'target_conditions': [
|
|
42
|
+
['_type=="loadable_module"', {
|
|
43
|
+
'product_extension': 'node',
|
|
44
|
+
'defines': [
|
|
45
|
+
'BUILDING_NODE_EXTENSION'
|
|
46
|
+
],
|
|
47
|
+
'xcode_settings': {
|
|
48
|
+
'OTHER_LDFLAGS': [
|
|
49
|
+
'-undefined dynamic_lookup'
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
'conditions': [
|
|
53
|
+
[ 'OS=="ios"', {
|
|
54
|
+
'mac_bundle': 1,
|
|
55
|
+
}],
|
|
56
|
+
],
|
|
57
|
+
}],
|
|
58
|
+
|
|
59
|
+
['_type=="static_library"', {
|
|
60
|
+
# set to `1` to *disable* the -T thin archive 'ld' flag.
|
|
61
|
+
# older linkers don't support this flag.
|
|
62
|
+
'standalone_static_library': '<(standalone_static_library)'
|
|
63
|
+
}],
|
|
64
|
+
|
|
65
|
+
['_type!="executable"', {
|
|
66
|
+
'conditions': [
|
|
67
|
+
[ 'OS=="android"', {
|
|
68
|
+
'cflags!': [ '-fPIE' ],
|
|
69
|
+
}]
|
|
70
|
+
]
|
|
71
|
+
}],
|
|
72
|
+
|
|
73
|
+
['_win_delay_load_hook=="true"', {
|
|
74
|
+
# If the addon specifies `'win_delay_load_hook': 'true'` in its
|
|
75
|
+
# binding.gyp, link a delay-load hook into the DLL. This hook ensures
|
|
76
|
+
# that the addon will work regardless of whether the node/iojs binary
|
|
77
|
+
# is named node.exe, iojs.exe, or something else.
|
|
78
|
+
'conditions': [
|
|
79
|
+
[ 'OS=="win"', {
|
|
80
|
+
'defines': [ 'HOST_BINARY=\"<(node_host_binary)<(EXECUTABLE_SUFFIX)\"', ],
|
|
81
|
+
'sources': [
|
|
82
|
+
'<(node_gyp_dir)/src/win_delay_load_hook.cc',
|
|
83
|
+
],
|
|
84
|
+
'msvs_settings': {
|
|
85
|
+
'VCLinkerTool': {
|
|
86
|
+
'DelayLoadDLLs': [ '<(node_host_binary)<(EXECUTABLE_SUFFIX)' ],
|
|
87
|
+
# Don't print a linker warning when no imports from either .exe
|
|
88
|
+
# are used.
|
|
89
|
+
'AdditionalOptions': [ '/ignore:4199' ],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}],
|
|
93
|
+
],
|
|
94
|
+
}],
|
|
95
|
+
],
|
|
96
|
+
|
|
97
|
+
'conditions': [
|
|
98
|
+
[ 'OS=="mac" or OS=="ios"', {
|
|
99
|
+
'defines': [
|
|
100
|
+
'_DARWIN_USE_64_BIT_INODE=1'
|
|
101
|
+
],
|
|
102
|
+
'xcode_settings': {
|
|
103
|
+
'DYLIB_INSTALL_NAME_BASE': '@rpath'
|
|
104
|
+
},
|
|
105
|
+
}],
|
|
106
|
+
[ 'OS=="aix"', {
|
|
107
|
+
'ldflags': [
|
|
108
|
+
'-Wl,-bimport:<(node_exp_file)'
|
|
109
|
+
],
|
|
110
|
+
}],
|
|
111
|
+
[ 'OS=="os400"', {
|
|
112
|
+
'ldflags': [
|
|
113
|
+
'-Wl,-bimport:<(node_exp_file)'
|
|
114
|
+
],
|
|
115
|
+
}],
|
|
116
|
+
[ 'OS=="zos"', {
|
|
117
|
+
'conditions': [
|
|
118
|
+
[ '"<!(echo $CC)" != "clang" and \
|
|
119
|
+
"<!(echo $CC)" != "ibm-clang64" and \
|
|
120
|
+
"<!(echo $CC)" != "ibm-clang"', {
|
|
121
|
+
'cflags': [
|
|
122
|
+
'-q64',
|
|
123
|
+
'-Wc,DLL',
|
|
124
|
+
'-qlonglong',
|
|
125
|
+
'-qenum=int',
|
|
126
|
+
'-qxclang=-fexec-charset=ISO8859-1'
|
|
127
|
+
],
|
|
128
|
+
'ldflags': [
|
|
129
|
+
'-q64',
|
|
130
|
+
'<(node_exp_file)',
|
|
131
|
+
],
|
|
132
|
+
}, {
|
|
133
|
+
'cflags': [
|
|
134
|
+
'-m64',
|
|
135
|
+
],
|
|
136
|
+
'ldflags': [
|
|
137
|
+
'-m64',
|
|
138
|
+
'<(node_exp_file)',
|
|
139
|
+
],
|
|
140
|
+
}],
|
|
141
|
+
],
|
|
142
|
+
'defines': [
|
|
143
|
+
'_ALL_SOURCE',
|
|
144
|
+
'MAP_FAILED=-1',
|
|
145
|
+
'_UNIX03_SOURCE',
|
|
146
|
+
],
|
|
147
|
+
}],
|
|
148
|
+
[ 'OS=="win"', {
|
|
149
|
+
'conditions': [
|
|
150
|
+
['node_engine=="chakracore"', {
|
|
151
|
+
'library_dirs': [ '<(node_root_dir)/$(ConfigurationName)' ],
|
|
152
|
+
'libraries': [ '<@(node_engine_libs)' ],
|
|
153
|
+
}],
|
|
154
|
+
['node_with_ltcg=="true"', {
|
|
155
|
+
'msvs_settings': {
|
|
156
|
+
'VCCLCompilerTool': {
|
|
157
|
+
'WholeProgramOptimization': 'true' # /GL, whole program optimization, needed for LTCG
|
|
158
|
+
},
|
|
159
|
+
'VCLibrarianTool': {
|
|
160
|
+
'AdditionalOptions': [
|
|
161
|
+
'/LTCG:INCREMENTAL', # incremental link-time code generation
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
'VCLinkerTool': {
|
|
165
|
+
'OptimizeReferences': 2, # /OPT:REF
|
|
166
|
+
'EnableCOMDATFolding': 2, # /OPT:ICF
|
|
167
|
+
'LinkIncremental': 1, # disable incremental linking
|
|
168
|
+
'AdditionalOptions': [
|
|
169
|
+
'/LTCG:INCREMENTAL', # incremental link-time code generation
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}]
|
|
174
|
+
],
|
|
175
|
+
'libraries': [
|
|
176
|
+
'-lkernel32.lib',
|
|
177
|
+
'-luser32.lib',
|
|
178
|
+
'-lgdi32.lib',
|
|
179
|
+
'-lwinspool.lib',
|
|
180
|
+
'-lcomdlg32.lib',
|
|
181
|
+
'-ladvapi32.lib',
|
|
182
|
+
'-lshell32.lib',
|
|
183
|
+
'-lole32.lib',
|
|
184
|
+
'-loleaut32.lib',
|
|
185
|
+
'-luuid.lib',
|
|
186
|
+
'-lodbc32.lib',
|
|
187
|
+
'-lDelayImp.lib',
|
|
188
|
+
'-l"<(node_lib_file)"'
|
|
189
|
+
],
|
|
190
|
+
'msvs_disabled_warnings': [
|
|
191
|
+
# warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>'
|
|
192
|
+
# needs to have dll-interface to be used by
|
|
193
|
+
# clients of class 'node::ObjectWrap'
|
|
194
|
+
4251
|
|
195
|
+
],
|
|
196
|
+
}, {
|
|
197
|
+
# OS!="win"
|
|
198
|
+
'defines': [
|
|
199
|
+
'_LARGEFILE_SOURCE',
|
|
200
|
+
'_FILE_OFFSET_BITS=64'
|
|
201
|
+
],
|
|
202
|
+
}],
|
|
203
|
+
[ 'OS in "freebsd openbsd netbsd solaris" or \
|
|
204
|
+
(OS in "linux android" and target_arch!="ia32")', {
|
|
205
|
+
'cflags': [ '-fPIC' ],
|
|
206
|
+
}],
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
}
|
package/bin/node-gyp.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import envPaths from 'env-paths'
|
|
4
|
+
import os from 'os'
|
|
5
|
+
import fs from 'fs'
|
|
6
|
+
import { Gyp } from '../lib/node-gyp.js'
|
|
7
|
+
import * as log from '../lib/log.js'
|
|
8
|
+
|
|
9
|
+
process.title = 'node-gyp'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 处理并执行选中的命令。
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const prog = new Gyp()
|
|
16
|
+
let completed = false
|
|
17
|
+
prog.parseArgv(process.argv)
|
|
18
|
+
prog.devDir = prog.opts.devdir
|
|
19
|
+
|
|
20
|
+
const homeDir = os.homedir()
|
|
21
|
+
if (prog.devDir) {
|
|
22
|
+
prog.devDir = prog.devDir.replace(/^~/, homeDir)
|
|
23
|
+
} else if (homeDir) {
|
|
24
|
+
prog.devDir = envPaths('node-gyp', { suffix: '' }).cache
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"node-gyp requires that the user's home directory is specified " +
|
|
28
|
+
'in either of the environmental variables HOME or USERPROFILE. ' +
|
|
29
|
+
'Overide with: --devdir /path/to/.node-gyp')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (prog.todo.length === 0) {
|
|
33
|
+
if (~process.argv.indexOf('-v') || ~process.argv.indexOf('--version')) {
|
|
34
|
+
log.stdout('v%s', prog.version)
|
|
35
|
+
} else {
|
|
36
|
+
log.stdout('%s', prog.usage())
|
|
37
|
+
}
|
|
38
|
+
process.exit(0)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
log.info('it worked if it ends with', 'ok')
|
|
42
|
+
log.verbose('cli', process.argv)
|
|
43
|
+
log.info('using', 'node-gyp@%s', prog.version)
|
|
44
|
+
log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform, process.arch)
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 如果传了 -C/--directory,切换到该目录。
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
const dir = prog.opts.directory
|
|
51
|
+
if (dir) {
|
|
52
|
+
try {
|
|
53
|
+
const stat = fs.statSync(dir)
|
|
54
|
+
if (stat.isDirectory()) {
|
|
55
|
+
log.info('chdir', dir)
|
|
56
|
+
process.chdir(dir)
|
|
57
|
+
} else {
|
|
58
|
+
log.warn('chdir', dir + ' is not a directory')
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {
|
|
61
|
+
if (e.code === 'ENOENT') {
|
|
62
|
+
log.warn('chdir', dir + ' is not a directory')
|
|
63
|
+
} else {
|
|
64
|
+
log.warn('chdir', 'error during chdir() "%s"', e.message)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 打印错误上下文信息
|
|
71
|
+
*/
|
|
72
|
+
const errorMessage = () => {
|
|
73
|
+
// 复制自 npm 的 lib/utils/error-handler.js
|
|
74
|
+
log.error('System', os.type() + ' ' + os.release())
|
|
75
|
+
log.error('command', process.argv
|
|
76
|
+
.map(JSON.stringify).join(' '))
|
|
77
|
+
log.error('cwd', process.cwd())
|
|
78
|
+
log.error('node -v', process.version)
|
|
79
|
+
log.error('node-gyp -v', 'v' + prog.package.version)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 打印最终诊断信息
|
|
84
|
+
*/
|
|
85
|
+
const issueMessage = () => {
|
|
86
|
+
errorMessage()
|
|
87
|
+
log.error('', ['Node-gyp failed to build your package.',
|
|
88
|
+
'Try to update npm and/or node-gyp and if it does not help file an issue with the package author.'
|
|
89
|
+
].join('\n'))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 依次执行队列中的命令
|
|
94
|
+
*/
|
|
95
|
+
const run = async () => {
|
|
96
|
+
const command = prog.todo.shift()
|
|
97
|
+
if (!command) {
|
|
98
|
+
// 完成!
|
|
99
|
+
completed = true
|
|
100
|
+
log.info('ok')
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const args = await prog.commands[command.name](command.args) ?? []
|
|
106
|
+
|
|
107
|
+
if (command.name === 'list') {
|
|
108
|
+
if (args.length) {
|
|
109
|
+
args.forEach((version) => log.stdout(version))
|
|
110
|
+
} else {
|
|
111
|
+
log.stdout('No node development files installed. Use `node-gyp install` to install a version.')
|
|
112
|
+
}
|
|
113
|
+
} else if (args.length >= 1) {
|
|
114
|
+
log.stdout(...args.slice(1))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 继续执行队列中的下一条命令
|
|
118
|
+
return run()
|
|
119
|
+
} catch (err) {
|
|
120
|
+
log.error(command.name + ' error')
|
|
121
|
+
log.error('stack', err.stack)
|
|
122
|
+
errorMessage()
|
|
123
|
+
log.error('not ok')
|
|
124
|
+
return process.exit(1)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
process.on('exit', function (code) {
|
|
129
|
+
if (!completed && !code) {
|
|
130
|
+
log.error('Completion callback never invoked!')
|
|
131
|
+
issueMessage()
|
|
132
|
+
process.exit(6)
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
process.on('uncaughtException', function (err) {
|
|
137
|
+
log.error('UNCAUGHT EXCEPTION')
|
|
138
|
+
log.error('stack', err.stack)
|
|
139
|
+
issueMessage()
|
|
140
|
+
process.exit(7)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// 开始执行给定命令!
|
|
144
|
+
run()
|