@flun/nodejs-mobile-gyp
v1.2.2
Published
Node.js for Mobile Apps native addon build tool (flun fork)
Downloads
1,111
Maintainers
Readme
@flun/nodejs-mobile-gyp
简介
移动端 Node.js 原生模块(Native Addon)的交叉编译工具;
用于为 nodejs-mobile 环境编译 C/C++ 原生模块,支持 Android 与 iOS 的交叉编译; 适用于官方 nodejs-mobile 及兼容的社区发行版 (如 OpenFlun/nodejs-mobile);
宿主平台支持 Windows / macOS / Linux,各平台所需的环境与工具见 安装前准备;
@flun/nodejs-mobile-react-native
在构建时会自动调用本包,无需手动安装;
本包是 nodejs-mobile-gyp 的 flun fork,后者又基于上游
node-gyp;
- GitHub:https://github.com/OpenFlun/nodejs-mobile-gyp
- gitee: https://gitee.com/OpenFlun/nodejs-mobile-gyp
- npm:https://www.npmjs.com/package/@flun/nodejs-mobile-gyp
与原版的差异
代码风格
| 项 | 原版 | 本 fork |
| -------- | ----------------------- | ------------------------------------------- |
| 模块系统 | CommonJS | ESM(package.json 的 type: "module") |
| 导出方式 | 文件内 module.exports | 末尾统一 export { ... } |
| 函数声明 | async function xxx | const xxx = async () =>(class 保留) |
| 注释 | 英文 | 中文 |
依赖升级
| 包 | 原版 | 本 fork | 原因 |
| ------------------- | ---------- | --------- | ------------------------------------------- |
| tar | ^6.1.2 | ^7.5.22 | 上游 v6 停更,有安全公告 |
| glob | ^10.3.10 | ^13.0.6 | 上游 v10 停更 |
| make-fetch-happen | ^13.0.0 | ^16.0.1 | 连带升级 cacache,去掉 tar@6 / glob@10 |
升级后依赖树干净,npm audit 0 vulnerabilities;
特性
- 为 nodejs-mobile 环境交叉编译 C/C++ 原生模块
- 支持 Android 与 iOS 目标,宿主可为 Windows / macOS / Linux
- 自动探测 Windows 下的 Python、Visual Studio、Git for Windows(MSYS2 POSIX 工具集)
- 跨平台路径处理统一转正斜杠,兼容 Windows 下的 gyp 生成器
- 依赖链升级至较新版本(make-fetch-happen、nopt、proc-log、which 等)
- 由
@flun/nodejs-mobile-react-native自动调用,通常无需手动安装
包目录结构
@flun/nodejs-mobile-gyp/
│
├── bin/
│ └── node-gyp.js # CLI 入口(#!/usr/bin/env node),创建 Gyp 实例并依次执行命令队列
│
├── lib/ # 核心实现,全部为 ESM
│ ├── node-gyp.js # Gyp 主类:参数解析、命令分发、usage 生成
│ ├── build.js # build 命令:调用 make / msbuild 编译原生模块
│ ├── clean.js # clean 命令:删除 build 目录
│ ├── configure.js # configure 命令:下载 headers、生成 config.gypi 与工程文件
│ ├── rebuild.js # rebuild 命令:依次执行 clean + configure + build
│ ├── install.js # install 命令:下载并解压指定版本的 Node 开发文件
│ ├── remove.js # remove 命令:删除指定版本的 Node 开发文件
│ ├── list.js # list 命令:列出已安装的 Node 开发文件版本
│ ├── create-config-gypi.js # 生成 config.gypi;Windows 上强制 MSVC 工具集、关闭 LTO
│ ├── process-release.js # 解析下载 URL、本地目录名、headers 与 node.lib 地址
│ ├── download.js # 基于 make-fetch-happen 的 HTTP 下载与 CA 读取
│ ├── find-node-directory.js # 推断 Node 安装根目录(用于 AIX / zOS)
│ ├── find-python.js # PythonFinder 类:动态定位 Python 3.6+(py 启动器 / 目录扫描)
│ ├── find-visualstudio.js # VisualStudioFinder 类:定位可用的 VS 安装(VS2013+,含 VS2026)
│ ├── Find-VisualStudio.cs # PowerShell 调用的 C# 脚本,枚举 VS 安装信息
│ ├── log.js # Logger 类 + proc-log 包装,分级着色日志
│ └── util.js # 通用工具:execFile 包装、注册表读取、候选文件查找
│
├── gyp/ # 内置的 gyp 工具(Python)
│ ├── pylib/gyp/ # gyp 核心 Python 模块
│ │ ├── input.py # 解析 .gyp / .gypi 文件
│ │ ├── common.py # 通用工具
│ │ ├── MSVS*.py # MSBuild / VS 工程生成
│ │ ├── msvs_emulation.py # VS 配置模拟
│ │ ├── xcode*.py # Xcode 工程生成
│ │ ├── mac_tool.py # macOS 工具链
│ │ ├── win_tool.py # Windows 工具链
│ │ └── generator/ # 各类生成器后端(make / msvs / ninja / xcode / cmake ...)
│ ├── pylib/packaging/ # gyp 依赖的 Python packaging 库(vendored)
│ ├── data/win/
│ │ └── large-pdb-shim.cc # Windows 大 PDB 兼容编译单元
│ ├── gyp # Python 启动脚本(Unix)
│ ├── gyp_main.py # gyp 主入口
│ ├── gyp.bat # Python 启动脚本(Windows)
│ ├── pyproject.toml # gyp 自身构建元数据(不随包发布)
│ ├── README.md # gyp 上游说明(不随包发布)
│ └── test_gyp.py # gyp 自测脚本(不随包发布)
│
├── src/
│ └── win_delay_load_hook.cc # Windows 加载延迟钩子(编译进每个原生模块)
│
├── addon.gypi # 所有原生模块共用的 gyp 配置
├── CHANGELOG.md # 版本变更记录
├── README.md # 本文件
├── LICENSE # 本包许可证(ISC)
├── macOS_Catalina_acid_test.sh # macOS Catalina 兼容性验证脚本(仅本地开发,不随包发布)
└── package.json # type: module,bin 命令名为 nodejs-mobile-gyp安装前准备
本包面向 Android / iOS 交叉编译,宿主平台支持情况:
| 宿主平台 | 目标:Android | 目标:iOS | | -------- | ------------ | -------- | | Windows | 完整支持 | 需 macOS | | macOS | 完整支持 | 完整支持 | | Linux | 完整支持 | 需 macOS |
各平台所需的构建环境如下;
通用要求
- Node.js:最低版本见
package.json的engines.node字段 - Python 3.6+:gyp 本身是 Python 程序,构建时必需
- 目标平台 SDK:
- Android:Android NDK(23–27 已验证)
- iOS:完整 Xcode(仅 macOS;Command Line Tools 单独不够)
Windows
Node.js:见engines.nodePython:3.6+,支持任意安装位置,见下方"自动探测"Visual Studio:VS2019 / VS2022 / VS2026(2026 已验证);需勾选"使用 C++ 的桌面开发"工作负载, 含 Windows SDK;VS2017 及更早受 Node 版本上限限制Android NDK:23–27(已验证);由@flun/nodejs-mobile-react-native自动定位Git for Windows:任意近期版本;自带整套 MSYS2 POSIX 工具集 (sh.exe、printf、xargs、sed、rm、mkdir等数十个命令), GNU make 执行 Makefile 所依赖的 Unix 命令均由它提供;位置自动探测(见下方)
为什么需要 Git for Windows? Android 原生模块通过 GNU make 构建,Makefile 中会调用
printf、xargs、sed等 Unix 命令;这些命令并非 Windows 自带,GNU make 需要一个 POSIX 环境来执行它们;Git for Windows 自带整套 MSYS2 POSIX 工具集(sh.exe、printf、xargs、sed、rm、mkdir等数十个命令),无需额外安装 MSYS2 或 Cygwin;
macOS
| 组件 | 要求 |
| ----------- | ----------------------------- |
| Node.js | 见 engines.node |
| Python | 3.6+ |
| Xcode | 完整 Xcode(必须,CLT 单独不够) |
| Android NDK | 仅构建 Android 目标时需 23–27 |
Linux
| 组件 | 要求 |
| ----------- | ---------------------------------------------------- |
| Node.js | 见 engines.node |
| Python | 3.6+ |
| 构建工具 | make、g++(apt install build-essential python3) |
| Android NDK | 仅构建 Android 目标时需 23–27 |
自动探测(Windows)
以下工具的安装位置由本包动态探测,无需手动指定路径(前提:工具已安装):
Python,依次尝试:
NODE_GYP_FORCE_PYTHON环境变量- 命令行
--python= PYTHON环境变量py.exe启动器(PATH 中、%SystemRoot%\py.exe、%SystemRoot%\System32\py.exe)py -0p枚举所有已注册 Pythonpython3/python命令- 扫描
%LOCALAPPDATA%\Programs\Python\Python*与%ProgramFiles%\Python*
Git for Windows 的
usr/bin目录(POSIX 工具集所在处,以sh.exe是否存在作为判据),依次尝试:- 注册表
HKLM\SOFTWARE\GitForWindows的InstallPath which git反推../usr/binPATH中的git.exe反推../usr/bin- 常见安装位置兜底
- 注册表
Android NDK:由
@flun/nodejs-mobile-react-native通过android.ndkDirectory定位,并注入make.exe、clang等工具路径;
本包不依赖任何随包分发的硬编码配置文件;上述探测均为运行时动态完成;仅 Visual Studio 的"版本号 → 版本年份 → toolset"对照表以常量形式内联在
lib/find-visualstudio.js中--这类信息由微软固定发布,无枚举接口,且随 VS 版本发布而更新, 不适合做成外部资源;
安装
npm i @flun/nodejs-mobile-gyp通常你不需要手动安装本包--它由 @flun/nodejs-mobile-react-native 在编译原生模块时自动调用;
Node 版本要求:本 fork 的依赖链(
make-fetch-happen、nopt、proc-log、which等)已升级到较新版本,要求比原版nodejs-mobile-gyp更高的 Node;具体最低版本见package.json的engines.node字段;若你的项目仍在使用较旧的 Node, 请改用原版nodejs-mobile-gyp;
命令行
快速开始
在需要编译原生模块的项目目录下执行:
npx @flun/nodejs-mobile-gyp rebuild --target=v18.20.4 --arch=arm64rebuild 依次执行 clean → configure → build;--target 指定目标 Node.js 版本,
--arch 指定目标架构;Android 与 iOS 的构建环境要求见 安装前准备;
调用方式
npx @flun/nodejs-mobile-gyp <command> [options]或在 package.json 的 scripts 中调用:
{
"scripts": {
"build-addon": "nodejs-mobile-gyp rebuild"
}
}命令
| 命令 | 说明 |
| ----------- | ---------------------------------------- |
| help | 显示帮助 |
| build | 调用 make / msbuild.exe 编译原生模块 |
| clean | 删除 build 目录(若存在) |
| configure | 为当前平台生成工程构建文件 |
| rebuild | 依次执行 clean → configure → build |
| install | 为指定版本安装 Node.js 头文件 |
| list | 列出已安装的 Node.js 头文件版本 |
| remove | 删除指定版本的 Node.js 头文件 |
参数
-v,--version:打印本包版本号-j n,--jobs n:并行运行make;max表示使用所有 CPU 核心--target=v6.2.1:目标 Node.js 版本(默认process.version)--silly,--loglevel=silly:输出全部进度日志--verbose,--loglevel=verbose:输出大部分进度日志--silent,--loglevel=silent:不输出任何日志debug,--debug:生成 Debug 构建(默认 Release)--release,--no-debug:生成 Release 构建-C $dir,--directory=$dir:在指定目录运行命令--make=$make:覆盖make命令(如gmake)--thin=yes:启用 thin 静态库--arch=$arch:目标架构(如ia32)--tarball=$path:从本地 tarball 获取头文件--devdir=$path:SDK 下载目录(默认为系统缓存目录)--ensure:已存在的头文件不重装--dist-url=$url:从自定义 URL 下载头文件 tarball--proxy=$url:下载时使用 HTTP(S) 代理--noproxy=$urls:下载时忽略代理的 URL 列表--cafile=$cafile:覆盖默认 CA 链(用于下载 tarball)--nodedir=$path:指定 Node 源码路径--python=$path:指定 Python 二进制路径--msvs-version=$version:指定 Visual Studio 版本或安装路径(仅 Windows;可填2022/2026或C:\...\BuildTools)--solution=$solution:指定 Visual Studio Solution 版本(仅 Windows)--force-process-config:强制用运行时的process.config生成config.gypi
函数方式
本包主要作为 CLI 工具使用,推荐通过 spawn / execFile 调用其命令行入口; 包本身也导出了 Gyp 类,但属于内部实现,接口可能随版本变化,不建议直接在代码中依赖;
参考配置
环境变量
上表中的命令选项(除 -v/--version 外),都可以用 npm_config_OPTION_NAME 形式的环境变量来设置;
选项名中的 - 替换为 _;
例如,把 devdir 设为 /tmp/.gyp:
Unix:
export npm_config_devdir=/tmp/.gypWindows:
set npm_config_devdir=c:\temp\.gypnpm 配置(npm v9 之前)
用 OPTION_NAME 形式:
npm config set [--global] devdir /tmp/.gyp注意:通过 npm config 设置的配置,只在本包 由 npm 调用时生效,直接运行 nodejs-mobile-gyp 不生效;
开发者参考
Windows 构建适配
原版 nodejs-mobile-gyp 在 Windows 上有若干问题,本 fork 逐一解决,涉及三方面;
1. 工具集与 LTO
原版默认走 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 工具链,会报:
MSB8020: 无法找到 ClangCL 的生成工具LNK1117: 选项"opt:lldltojobs=2"中的语法错误
本 fork 强制走 MSVC 工具集并关闭 LTO,避免上述报错;工具集版本从 find-visualstudio 的探测结果动态获取(v140 / v141
/ v142 / v143 / v145...),不写死;
2. GNU make 的 POSIX 环境
Android 原生模块通过 GNU make 构建,其 Makefile 会调用 printf、xargs、sed 等 Unix 命令;GNU make 需要一个 POSIX
shell(sh.exe)来执行它们;Windows 上若无,会直接报 CreateProcess(NULL, printf ...) failed;Git for Windows 自带整套 POSIX
工具集;本 fork 会自动定位其 usr/bin 并前置到 PATH,详见 安装前准备 的"自动探测(Windows)";
3. 路径分隔符
gyp 生成的 Makefile 中,路径原本会带上 Windows 的反斜杠(如 src\bufferutil.o),导致 sh / sed / make 解析失败;本 fork
在 gyp 的路径生成环节统一转成正斜杠;该改动在非 Windows 平台上是 no-op;
具体改动清单
构建工具链
lib/create-config-gypi.js- 改动:生成
config.gypi时把clang置 0、enable_lto/enable_thin_lto置'false'、lto_jobs置空,避免common.gypi切到 ClangCL 并向 MSVC 传 LTO 参数
- 改动:生成
lib/configure.js- 改动:调用 gyp 时追加
-Gmsvs_toolset=<探测到的 toolset>,不再写死v145
- 改动:调用 gyp 时追加
lib/find-visualstudio.js- 改动:支持 VS2013+,含最新 VS2026(版本号 18,
versionYear=2026,toolsetv145)
- 改动:支持 VS2013+,含最新 VS2026(版本号 18,
gyp/pylib/gyp/MSVSSettings.py- 改动:注册
ExternalWarningLevel(MSBuild 属性),供addon.gypi使用
- 改动:注册
addon.gypi- 改动:Windows 下追加
/external:anglebrackets+ExternalWarningLevel: TurnOffAllWarnings,只静音外部头(Node / V8)的警告
- 改动:Windows 下追加
跨平台路径
gyp/pylib/gyp/common.py:RelativePath返回值统一转正斜杠gyp/pylib/gyp/generator/make.py:Absolutify返回正斜杠;新增slashpath供mkdir使用; Windows 下跳过node_modules中的超长 gypi 依赖
Windows 运行时探测
lib/find-python.js:重写:移除硬编码版本列表,改为py.exe候选 +py -0p枚举 + 目录扫描;run()显式检查execFile的 errlib/build.js:区分"宿主 Windows"与"Android 交叉编译";自动探测sh.exe并前置到 PATH; 为 Python 创建python3.cmdshim
兼容性与健壮性
proc-log新版本兼容:新版把日志级别函数与pause/resume挂在默认导出的log对象下;本 fork 已按此调整lib/log.js,否则configure阶段会抛TypeError;- 弃用 API 清理:
lib/process-release.js不再用url.resolve()/url.parse(),改用 WHATWGURL,消除DEP0169警告; - 依赖脚本放行:
package.json显式声明allowScripts,适配新版 npm 默认禁止依赖执行安装脚本的行为;
常见问题
graceful-fs是 CJS,命名导入会失败 写成import gracefulFs from 'graceful-fs',再从 default 解构const { openSync, closeSync } = gracefulFs;tar@7没有 default export 写成import * as tar from 'tar';proc-log的解构import procLog from 'proc-log',再把需要的函数从 default 里解构后统一导出;PowerShell 写文件会加 BOM
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;ESM 不支持动态
require('./' + command)lib/node-gyp.js原本用require('./' + command)动态加载命令模块,ESM 下改为在顶部静态 import 所有命令, 再用静态映射表组装this.commands;__dirname/__filename在 ESM 中不存在 用fileURLToPath(import.meta.url)重建;非 Windows 平台不引入
find-visualstudio.js该模块依赖 Windows 专属的path.win32和注册表操作,保持原版的"仅在 Windows 上条件加载"逻辑;
许可证
ISC
贡献
上游文档:
