mirror of
https://github.com/hotwa/luci-app-openclaw.git
synced 2026-03-30 20:25:44 +00:00
release: v1.0.2 — ARM64 musl patchelf 修复、ICU 数据
This commit is contained in:
12
CHANGELOG.md
12
CHANGELOG.md
@@ -4,6 +4,18 @@
|
|||||||
|
|
||||||
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)。
|
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)。
|
||||||
|
|
||||||
|
## [1.0.2] - 2026-03-02
|
||||||
|
|
||||||
|
### 修复
|
||||||
|
- **P0** ARM64 musl: Gateway 崩溃循环 — `process.execPath` 返回 musl 链接器路径导致 `child_process.fork()` 失败
|
||||||
|
- 使用 `patchelf` 直接修改 node ELF 二进制的 interpreter 和 rpath,替代 ld-musl wrapper 方案
|
||||||
|
- 子进程通过 `process.execPath` fork 时可正确找到 node 二进制
|
||||||
|
- **P0** ARM64 musl: Unicode property escapes 正则失败 (`\p{Emoji_Presentation}`) — 缺少 `NODE_ICU_DATA` 环境变量
|
||||||
|
- init.d、openclaw-env、oc-config.sh 所有入口均添加 `NODE_ICU_DATA` 环境变量
|
||||||
|
|
||||||
|
### 改进
|
||||||
|
- `build-node-musl.sh` 构建验证阶段新增 `process.execPath` 输出检查
|
||||||
|
|
||||||
## [1.0.1] - 2026-03-02
|
## [1.0.1] - 2026-03-02
|
||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
|
|||||||
132
README.md
132
README.md
@@ -13,12 +13,60 @@
|
|||||||
|
|
||||||
| 项目 | 要求 |
|
| 项目 | 要求 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 架构 | x86_64 或 aarch64 |
|
| 架构 | x86_64 或 aarch64 (ARM64) |
|
||||||
| C 库 | glibc 或 musl(自动检测) |
|
| C 库 | glibc 或 musl(自动检测) |
|
||||||
| 依赖 | luci-compat, luci-base, curl, openssl-util |
|
| 依赖 | luci-compat, luci-base, curl, openssl-util |
|
||||||
| 存储 | 1.5GB 以上可用空间 |
|
| 存储 | 1.5GB 以上可用空间 |
|
||||||
| 内存 | 推荐 2GB 及以上 |
|
| 内存 | 推荐 2GB 及以上 |
|
||||||
|
|
||||||
|
### 🖥️ 兼容性矩阵
|
||||||
|
|
||||||
|
#### 支持的架构 × C 库组合
|
||||||
|
|
||||||
|
| 架构 | C 库 | Node.js 来源 | 状态 |
|
||||||
|
|------|------|-------------|------|
|
||||||
|
| x86_64 | musl | [unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org/) | ✅ 已验证 |
|
||||||
|
| x86_64 | glibc | [nodejs.org](https://nodejs.org/) 官方 | ✅ 支持 |
|
||||||
|
| aarch64 | musl | 项目自托管(Alpine 打包,含完整依赖) | ✅ 已验证 |
|
||||||
|
| aarch64 | glibc | [nodejs.org](https://nodejs.org/) 官方 | ✅ 支持 |
|
||||||
|
| armv7l / armv6l | - | — | ❌ 不支持 |
|
||||||
|
|
||||||
|
> **说明**:Node.js 22+ 不再提供 32 位 ARM 预编译包,因此不支持 armv7l/armv6l(如 MT7621 路由器)。
|
||||||
|
|
||||||
|
#### 支持的 OpenWrt 版本
|
||||||
|
|
||||||
|
| OpenWrt 版本 | LuCI 版本 | 验证状态 | 说明 |
|
||||||
|
|-------------|-----------|---------|------|
|
||||||
|
| 24.x (iStoreOS 24.10) | LuCI 24.x | ✅ 已验证 | 推荐版本 |
|
||||||
|
| 23.05 | LuCI openwrt-23.05 | ✅ 支持 | |
|
||||||
|
| 22.03 (iStoreOS 22.03) | LuCI openwrt-22.03 | ✅ 已验证 | 需自托管 Node.js(ARM64 musl) |
|
||||||
|
| 21.02 | LuCI openwrt-21.02 | ⚠️ 应兼容 | 未测试,procd / LuCI API 兼容 |
|
||||||
|
| 19.07 | LuCI openwrt-19.07 | ⚠️ 应兼容 | 未测试 |
|
||||||
|
| 18.06 及更早 | LuCI 旧版 | ❌ 不保证 | procd API 可能不兼容 |
|
||||||
|
|
||||||
|
> 插件使用标准 procd init 和 LuCI CBI (luci-compat) 接口,理论上兼容 OpenWrt 19.07+。
|
||||||
|
|
||||||
|
#### 已验证的典型设备
|
||||||
|
|
||||||
|
| 设备 / 平台 | 架构 | 系统 | 验证结果 |
|
||||||
|
|------------|------|------|---------|
|
||||||
|
| N100 / N5105 软路由 | x86_64 musl | iStoreOS 24.10.5 | ✅ 通过 |
|
||||||
|
| 晶晨 S905 系列 (Cortex-A53) | aarch64 musl | iStoreOS 22.03.7 | ✅ 通过 |
|
||||||
|
| Raspberry Pi 4/5 | aarch64 | OpenWrt 23.05+ | ✅ 应支持 |
|
||||||
|
| FriendlyElec R4S/R5S | aarch64 | OpenWrt / FriendlyWrt | ✅ 应支持 |
|
||||||
|
| 通用 x86 虚拟机 (PVE/ESXi) | x86_64 | OpenWrt 22.03+ | ✅ 应支持 |
|
||||||
|
| MT7621 路由器 (如 Redmi AC2100) | mipsel / armv7l | — | ❌ 不支持 |
|
||||||
|
|
||||||
|
#### ARM64 musl 特别说明
|
||||||
|
|
||||||
|
ARM64 + musl 的 OpenWrt 设备(绝大多数 ARM64 路由器)使用**项目自托管的 Node.js 包**:
|
||||||
|
|
||||||
|
- 基于 Alpine Linux 3.21 ARM64 环境打包
|
||||||
|
- 包含完整的共享库(libstdc++、libssl、libicu 等)和 musl 动态链接器
|
||||||
|
- 包含完整 ICU 国际化数据(`icudt74l.dat`)
|
||||||
|
- 通过 wrapper 脚本使用打包的 musl 链接器启动,**不依赖系统库版本**
|
||||||
|
- 因此即使系统是 OpenWrt 22.03(musl 1.2.3)也能正常运行 Alpine 3.21 编译的 Node.js
|
||||||
|
|
||||||
## 📦 安装
|
## 📦 安装
|
||||||
|
|
||||||
### 方式一:.run 自解压包(推荐)
|
### 方式一:.run 自解压包(推荐)
|
||||||
@@ -85,23 +133,7 @@ sh /etc/uci-defaults/99-openclaw
|
|||||||
rm -f /tmp/luci-indexcache /tmp/luci-modulecache/*
|
rm -f /tmp/luci-indexcache /tmp/luci-modulecache/*
|
||||||
```
|
```
|
||||||
|
|
||||||
## <EFBFBD> 一键部署下载
|
## 🔰 首次使用
|
||||||
|
|
||||||
OpenClaw 支持全平台一键部署,请根据你的设备选择对应方式。
|
|
||||||
|
|
||||||
> **💡 提示**:OpenWrt 路由器请直接使用下方 [📦 安装](#-安装) 章节的命令,无需使用本节下载包。
|
|
||||||
|
|
||||||
| 平台 | 下载链接 | 说明 |
|
|
||||||
|------|----------|------|
|
|
||||||
| 🐧 Linux (Ubuntu/Debian) | [夸克网盘](https://pan.quark.cn/s/c25bb5c20db1) | 或直接 `curl -fsSL "https://alist.910501.xyz/d/openclaw/install.sh?sign=RUSBfm1vy35Z-2S86e-Hr0s1bR2u_rATHXEpY888zi8=:0" \| bash` |
|
|
||||||
| 🪟 Windows (Win10/Win11) | [夸克网盘](https://pan.quark.cn/s/af01a152dad7) | 解压后右键「一键安装.bat」以管理员身份运行 |
|
|
||||||
| 🍎 macOS (Intel & Apple Silicon) | [夸克网盘](https://pan.quark.cn/s/99bad2c03e5c) | 解压后 `bash setup.sh` 授权,再双击「一键安装.command」 |
|
|
||||||
| 🐂 飞牛 NAS (FnOS) | [夸克网盘](https://pan.quark.cn/s/fea2552a1b73) | 离线 FPK 包,在应用商店「手动安装」 |
|
|
||||||
| 📡 OpenWrt 路由器 | [GitHub Releases](https://github.com/10000ge10000/luci-app-openclaw/releases/latest) | 见下方安装章节 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## <20>🔰 首次使用
|
|
||||||
|
|
||||||
1. 打开 LuCI → 服务 → OpenClaw,点击「安装运行环境」
|
1. 打开 LuCI → 服务 → OpenClaw,点击「安装运行环境」
|
||||||
2. 安装完成后服务会自动启动,点击「刷新页面」查看状态
|
2. 安装完成后服务会自动启动,点击「刷新页面」查看状态
|
||||||
@@ -134,64 +166,6 @@ luci-app-openclaw/
|
|||||||
└── .github/workflows/build.yml # GitHub Actions
|
└── .github/workflows/build.yml # GitHub Actions
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📡 OpenWrt 路由器专属说明
|
|
||||||
|
|
||||||
### 为什么选择路由器部署?
|
|
||||||
|
|
||||||
路由器 24 小时在线,天然适合作为 AI 网关的宿主——家里所有设备共享同一个 AI 服务,Telegram / Discord 消息也能全天候响应,无需常开电脑。
|
|
||||||
|
|
||||||
### 支持的设备
|
|
||||||
|
|
||||||
| 架构 | 典型设备 | 支持状态 |
|
|
||||||
|------|----------|----------|
|
|
||||||
| x86_64 | N100 / N5105 软路由、iStoreOS 小主机 | ✅ 完全支持 |
|
|
||||||
| aarch64 | Raspberry Pi 4/5、R4S、部分 ARM64 路由器 | ✅ 完全支持 |
|
|
||||||
| 32 位 ARM | 老款 MT7620 / MT7621 路由器 | ❌ 不支持(Node.js 22 无 32 位包) |
|
|
||||||
|
|
||||||
### 安装步骤(OpenWrt / iStoreOS)
|
|
||||||
|
|
||||||
**第一步:安装 LuCI 插件**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 推荐:.run 自解压包,一行搞定
|
|
||||||
wget https://github.com/10000ge10000/luci-app-openclaw/releases/latest/download/luci-app-openclaw.run
|
|
||||||
sh luci-app-openclaw.run
|
|
||||||
```
|
|
||||||
|
|
||||||
**第二步:安装 OpenClaw 运行环境**
|
|
||||||
|
|
||||||
打开 LuCI → **服务** → **OpenClaw** → 点击「📦 安装运行环境」,脚本会自动完成:
|
|
||||||
- 检测 CPU 架构(x86_64 / aarch64)
|
|
||||||
- 检测 C 库类型(glibc / musl,绝大多数 OpenWrt 为 musl)
|
|
||||||
- 下载对应 Node.js 22 预编译包
|
|
||||||
- 安装 pnpm 和 OpenClaw 本体
|
|
||||||
|
|
||||||
> **网络慢?** 可在路由器 SSH 中指定国内镜像加速 Node.js 下载:
|
|
||||||
> ```bash
|
|
||||||
> NODE_MIRROR=https://npmmirror.com/mirrors/node openclaw-env setup
|
|
||||||
> ```
|
|
||||||
|
|
||||||
**第三步:配置 AI 模型和消息渠道**
|
|
||||||
|
|
||||||
进入「**配置管理**」页面,在内嵌 Web 终端中使用交互式向导,选数字即可完成配置,支持:
|
|
||||||
- OpenAI / Anthropic Claude / Google Gemini / DeepSeek / GitHub Copilot / OpenRouter / 通义千问 / Grok / Groq / 硅基流动 等 12+ 家提供商
|
|
||||||
- Telegram / Discord / 飞书 / Slack 消息渠道
|
|
||||||
|
|
||||||
**第四步:用 Telegram 与 AI 对话**
|
|
||||||
|
|
||||||
配置完 Telegram Bot Token 后,重启网关即可在 Telegram 直接给 Bot 发消息,路由器全天候在线响应。
|
|
||||||
|
|
||||||
### 与其他平台脚本的区别
|
|
||||||
|
|
||||||
| 对比项 | Linux/Mac/Win 脚本 | OpenWrt 插件 |
|
|
||||||
|--------|-------------------|--------------|
|
|
||||||
| 管理界面 | 命令行菜单 | LuCI 可视化界面 |
|
|
||||||
| 开机自启 | 系统服务 / 守护进程 | procd 托管,崩溃自动重启 |
|
|
||||||
| 安装包格式 | .sh / .bat / .command | .run / .ipk |
|
|
||||||
| Node.js 来源 | 官方 + npm 镜像 | 自动检测 musl/glibc,按需拉取 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ❓ 常见问题
|
## ❓ 常见问题
|
||||||
|
|
||||||
**安装后 LuCI 菜单没有出现**
|
**安装后 LuCI 菜单没有出现**
|
||||||
@@ -218,7 +192,11 @@ NODE_MIRROR=https://npmmirror.com/mirrors/node openclaw-env setup
|
|||||||
|
|
||||||
**是否支持 ARM 路由器**
|
**是否支持 ARM 路由器**
|
||||||
|
|
||||||
支持 aarch64(ARM64)。不支持 32 位 ARM,Node.js 22 没有 32 位预编译包。
|
支持 aarch64(ARM64),包括晶晨 S905 系列、Raspberry Pi 4/5、R4S/R5S 等。ARM64 musl 设备使用项目自托管的 Node.js 包,自带完整依赖库,不依赖系统库版本。**不支持** 32 位 ARM(armv7l/armv6l),Node.js 22 没有 32 位预编译包。
|
||||||
|
|
||||||
|
**ARM64 设备安装后 Node.js 显示 Segmentation fault**
|
||||||
|
|
||||||
|
旧版 OpenWrt(如 22.03)的系统 musl 版本较低,与新版 Node.js 不兼容。请确保使用最新版本的 `openclaw-env`(v1.0.1+),它会自动下载包含独立 musl 链接器的自托管 Node.js 包。
|
||||||
|
|
||||||
## 🤝 贡献
|
## 🤝 贡献
|
||||||
|
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ HOME="$OC_DATA" \
|
|||||||
OPENCLAW_HOME="$OC_DATA" \
|
OPENCLAW_HOME="$OC_DATA" \
|
||||||
OPENCLAW_STATE_DIR="${OC_DATA}/.openclaw" \
|
OPENCLAW_STATE_DIR="${OC_DATA}/.openclaw" \
|
||||||
OPENCLAW_CONFIG_PATH="$CONFIG_FILE" \
|
OPENCLAW_CONFIG_PATH="$CONFIG_FILE" \
|
||||||
|
NODE_ICU_DATA="${NODE_BASE}/share/icu" \
|
||||||
NODE_BASE="$NODE_BASE" \
|
NODE_BASE="$NODE_BASE" \
|
||||||
OC_GLOBAL="$OC_GLOBAL" \
|
OC_GLOBAL="$OC_GLOBAL" \
|
||||||
OC_DATA="$OC_DATA" \
|
OC_DATA="$OC_DATA" \
|
||||||
@@ -204,6 +205,7 @@ procd_set_param env \
|
|||||||
OC_CONFIG_PORT="$pty_port" \
|
OC_CONFIG_PORT="$pty_port" \
|
||||||
OC_PTY_TOKEN="$pty_token" \
|
OC_PTY_TOKEN="$pty_token" \
|
||||||
OC_CONFIG_SCRIPT="/usr/share/openclaw/oc-config.sh" \
|
OC_CONFIG_SCRIPT="/usr/share/openclaw/oc-config.sh" \
|
||||||
|
NODE_ICU_DATA="${NODE_BASE}/share/icu" \
|
||||||
NODE_BASE="$NODE_BASE" \
|
NODE_BASE="$NODE_BASE" \
|
||||||
OC_GLOBAL="$OC_GLOBAL" \
|
OC_GLOBAL="$OC_GLOBAL" \
|
||||||
OC_DATA="$OC_DATA" \
|
OC_DATA="$OC_DATA" \
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ NODE_MUSL_MIRROR="https://unofficial-builds.nodejs.org/download/release"
|
|||||||
NODE_SELF_HOST="https://github.com/10000ge10000/luci-app-openclaw/releases/download/node-bins"
|
NODE_SELF_HOST="https://github.com/10000ge10000/luci-app-openclaw/releases/download/node-bins"
|
||||||
|
|
||||||
export PATH="${NODE_BASE}/bin:${OC_GLOBAL}/bin:$PATH"
|
export PATH="${NODE_BASE}/bin:${OC_GLOBAL}/bin:$PATH"
|
||||||
|
export NODE_ICU_DATA="${NODE_BASE}/share/icu"
|
||||||
|
|
||||||
log_info() { echo " [✓] $1"; }
|
log_info() { echo " [✓] $1"; }
|
||||||
log_warn() { echo " [!] $1"; }
|
log_warn() { echo " [!] $1"; }
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export HOME="$OC_DATA"
|
|||||||
export OPENCLAW_HOME="$OC_DATA"
|
export OPENCLAW_HOME="$OC_DATA"
|
||||||
export OPENCLAW_STATE_DIR="$OC_STATE_DIR"
|
export OPENCLAW_STATE_DIR="$OC_STATE_DIR"
|
||||||
export OPENCLAW_CONFIG_PATH="$CONFIG_FILE"
|
export OPENCLAW_CONFIG_PATH="$CONFIG_FILE"
|
||||||
|
export NODE_ICU_DATA="${NODE_BASE}/share/icu"
|
||||||
export PATH="${NODE_BASE}/bin:${OC_GLOBAL}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
export PATH="${NODE_BASE}/bin:${OC_GLOBAL}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
|
||||||
# ── 查找 openclaw 入口 ──
|
# ── 查找 openclaw 入口 ──
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# 在 Alpine ARM64 Docker 容器内运行
|
# 在 Alpine ARM64 Docker 容器内运行
|
||||||
# 环境变量: NODE_VER (目标版本号), /output (输出目录)
|
# 环境变量: NODE_VER (目标版本号), /output (输出目录)
|
||||||
|
#
|
||||||
|
# 打包策略:
|
||||||
|
# 使用 patchelf 修改 node 二进制的 ELF interpreter 和 rpath,
|
||||||
|
# 使其直接使用打包的 musl 链接器和共享库,无需 LD_LIBRARY_PATH。
|
||||||
|
# 这样 process.execPath 返回正确的 node 路径,子进程 fork 也能正常工作。
|
||||||
|
# 安装路径固定为 /opt/openclaw/node (与 openclaw-env 一致)。
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
apk add --no-cache nodejs npm xz
|
INSTALL_PREFIX="/opt/openclaw/node"
|
||||||
|
|
||||||
|
apk add --no-cache nodejs npm xz icu-data-full patchelf
|
||||||
|
|
||||||
ACTUAL_VER=$(node --version | sed 's/^v//')
|
ACTUAL_VER=$(node --version | sed 's/^v//')
|
||||||
echo "Alpine Node.js version: v${ACTUAL_VER} (requested: v${NODE_VER})"
|
echo "Alpine Node.js version: v${ACTUAL_VER} (requested: v${NODE_VER})"
|
||||||
@@ -13,27 +21,87 @@ PKG_NAME="node-v${NODE_VER}-linux-arm64-musl"
|
|||||||
PKG_DIR="/tmp/${PKG_NAME}"
|
PKG_DIR="/tmp/${PKG_NAME}"
|
||||||
mkdir -p "${PKG_DIR}/bin" "${PKG_DIR}/lib/node_modules" "${PKG_DIR}/include/node"
|
mkdir -p "${PKG_DIR}/bin" "${PKG_DIR}/lib/node_modules" "${PKG_DIR}/include/node"
|
||||||
|
|
||||||
cp "$(which node)" "${PKG_DIR}/bin/"
|
# 复制 node 二进制
|
||||||
|
cp "$(which node)" "${PKG_DIR}/bin/node"
|
||||||
chmod +x "${PKG_DIR}/bin/node"
|
chmod +x "${PKG_DIR}/bin/node"
|
||||||
|
|
||||||
|
# 收集 node 依赖的所有共享库 (Alpine node 是动态链接的)
|
||||||
|
echo "=== Collecting shared libraries ==="
|
||||||
|
LIB_DIR="${PKG_DIR}/lib"
|
||||||
|
ldd "$(which node)" 2>/dev/null | while read -r line; do
|
||||||
|
# 解析 ldd 输出: libxxx.so => /usr/lib/libxxx.so (0x...)
|
||||||
|
lib_path=$(echo "$line" | grep -oE '/[^ ]+\.so[^ ]*' | head -1)
|
||||||
|
if [ -n "$lib_path" ] && [ -f "$lib_path" ]; then
|
||||||
|
cp -L "$lib_path" "$LIB_DIR/" 2>/dev/null || true
|
||||||
|
echo " + $(basename "$lib_path")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# 确保 musl 动态链接器也在
|
||||||
|
if [ -f /lib/ld-musl-aarch64.so.1 ]; then
|
||||||
|
cp -L /lib/ld-musl-aarch64.so.1 "$LIB_DIR/" 2>/dev/null || true
|
||||||
|
echo " + ld-musl-aarch64.so.1"
|
||||||
|
fi
|
||||||
|
echo "Libraries collected: $(ls "$LIB_DIR"/*.so* 2>/dev/null | wc -l) files"
|
||||||
|
|
||||||
|
# 用 patchelf 修改 node 二进制:
|
||||||
|
# - interpreter 指向打包的 musl 链接器 (绝对路径,对应安装后的位置)
|
||||||
|
# - rpath 指向打包的 lib 目录
|
||||||
|
echo "=== Patching ELF binary ==="
|
||||||
|
patchelf --set-interpreter "${INSTALL_PREFIX}/lib/ld-musl-aarch64.so.1" "${PKG_DIR}/bin/node"
|
||||||
|
patchelf --set-rpath "${INSTALL_PREFIX}/lib" "${PKG_DIR}/bin/node"
|
||||||
|
echo " interpreter: ${INSTALL_PREFIX}/lib/ld-musl-aarch64.so.1"
|
||||||
|
echo " rpath: ${INSTALL_PREFIX}/lib"
|
||||||
|
|
||||||
|
# 复制 ICU 完整数据 (npm 的 Intl.Collator 需要)
|
||||||
|
echo "=== Copying ICU data ==="
|
||||||
|
ICU_DAT=$(find /usr/share/icu -name "icudt*.dat" 2>/dev/null | head -1)
|
||||||
|
if [ -n "$ICU_DAT" ] && [ -f "$ICU_DAT" ]; then
|
||||||
|
mkdir -p "${PKG_DIR}/share/icu"
|
||||||
|
cp "$ICU_DAT" "${PKG_DIR}/share/icu/"
|
||||||
|
echo " + $(basename "$ICU_DAT") ($(du -h "$ICU_DAT" | cut -f1))"
|
||||||
|
else
|
||||||
|
echo " WARNING: ICU data file not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 创建 node wrapper 脚本 (只设置 NODE_ICU_DATA,ELF 层面已解决链接器和库路径)
|
||||||
|
cat > "${PKG_DIR}/bin/node-wrapper" << 'NODEWRAPPER'
|
||||||
|
#!/bin/sh
|
||||||
|
SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
export NODE_ICU_DATA="${SELF_DIR}/../share/icu"
|
||||||
|
exec "${SELF_DIR}/node" "$@"
|
||||||
|
NODEWRAPPER
|
||||||
|
chmod +x "${PKG_DIR}/bin/node-wrapper"
|
||||||
|
|
||||||
# 复制 npm
|
# 复制 npm
|
||||||
if [ -d /usr/lib/node_modules/npm ]; then
|
if [ -d /usr/lib/node_modules/npm ]; then
|
||||||
cp -r /usr/lib/node_modules/npm "${PKG_DIR}/lib/node_modules/"
|
cp -r /usr/lib/node_modules/npm "${PKG_DIR}/lib/node_modules/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 创建 npm wrapper
|
# 创建 npm wrapper (直接调用 patchelf 后的 node,只需设置 ICU)
|
||||||
printf '#!/bin/sh\nexec "$(dirname "$0")/node" "$(dirname "$0")/../lib/node_modules/npm/bin/npm-cli.js" "$@"\n' \
|
cat > "${PKG_DIR}/bin/npm" << 'NPMWRAPPER'
|
||||||
> "${PKG_DIR}/bin/npm"
|
#!/bin/sh
|
||||||
|
SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
export NODE_ICU_DATA="${SELF_DIR}/../share/icu"
|
||||||
|
exec "${SELF_DIR}/node" "${SELF_DIR}/../lib/node_modules/npm/bin/npm-cli.js" "$@"
|
||||||
|
NPMWRAPPER
|
||||||
# 创建 npx wrapper
|
# 创建 npx wrapper
|
||||||
printf '#!/bin/sh\nexec "$(dirname "$0")/node" "$(dirname "$0")/../lib/node_modules/npm/bin/npx-cli.js" "$@"\n' \
|
cat > "${PKG_DIR}/bin/npx" << 'NPXWRAPPER'
|
||||||
> "${PKG_DIR}/bin/npx"
|
#!/bin/sh
|
||||||
|
SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
export NODE_ICU_DATA="${SELF_DIR}/../share/icu"
|
||||||
|
exec "${SELF_DIR}/node" "${SELF_DIR}/../lib/node_modules/npm/bin/npx-cli.js" "$@"
|
||||||
|
NPXWRAPPER
|
||||||
chmod +x "${PKG_DIR}/bin/npm" "${PKG_DIR}/bin/npx"
|
chmod +x "${PKG_DIR}/bin/npm" "${PKG_DIR}/bin/npx"
|
||||||
|
|
||||||
# 验证
|
# 验证 (需要将打包内容放到目标路径来测试 patchelf 结果)
|
||||||
echo "=== Verification ==="
|
echo "=== Verification ==="
|
||||||
"${PKG_DIR}/bin/node" --version
|
mkdir -p "${INSTALL_PREFIX}"
|
||||||
"${PKG_DIR}/bin/node" -e "console.log(process.arch, process.platform, process.versions.modules)"
|
cp -a "${PKG_DIR}"/* "${INSTALL_PREFIX}/"
|
||||||
"${PKG_DIR}/bin/npm" --version 2>/dev/null || echo "npm wrapper created"
|
"${INSTALL_PREFIX}/bin/node" --version
|
||||||
|
"${INSTALL_PREFIX}/bin/node" -e "console.log('execPath:', process.execPath)"
|
||||||
|
"${INSTALL_PREFIX}/bin/node" -e "console.log(process.arch, process.platform, process.versions.modules)"
|
||||||
|
NODE_ICU_DATA="${INSTALL_PREFIX}/share/icu" "${INSTALL_PREFIX}/bin/npm" --version 2>/dev/null || echo "npm needs ICU data"
|
||||||
|
rm -rf "${INSTALL_PREFIX}"
|
||||||
|
|
||||||
# 打包
|
# 打包
|
||||||
cd /tmp
|
cd /tmp
|
||||||
|
|||||||
Reference in New Issue
Block a user