Files
webui4frpc/packaging/macos/build_pkg.sh
JianFeeeee 15b1dcce8f feat: 原生安装包 — deb/rpm/systemd + NSIS setup.exe + macOS pkg
此前交付的 tar.gz/zip 仅是解压直用包,补齐真正的平台安装包:
- Linux: .deb (dpkg-deb) 与 .rpm (rpmbuild),装 systemd 单元 + 专用
  系统账号 + /etc/webui4frpc 配置,非 root 运行 + 加固
- Windows: NSIS setup.exe,向导收集监听地址/凭据,注册卸载器 +
  防火墙放行(amd64/arm64)
- macOS: .pkg(在 Linux 上手工 xar+mkbom 组装 flat package),launchd
  开机自启 + env 配置文件(amd64/arm64)
- scripts/release.sh 纳入 build_installers.sh 阶段;README 增「安装」
  章节逐平台说明

已知限制:rpmbuild 无法在非 RHEL 主机交叉构建 aarch64(Debian rpm
只有 x86_64 构建 arch),aarch64 rpm 需在原生 ARM 机器构建;Linux/ARM
场景已由 deb-arm64 覆盖。
2026-08-28 08:36:55 +08:00

188 lines
6.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# 在 Linux 上手工组装 macOS .pkg (flat package)。
# macOS 的 pkgbuild/productbuild 不可用,因此用 xar + mkbom 手搓 flat package
#
# archive.xar
# ├── Distribution 安装器界面描述 (choices / title)
# └── webui4frpc.pkg/
# ├── PackageInfo 组件元数据 + postinstall 声明
# ├── Bom 文件清单 (mkbom 生成)
# ├── Payload 根文件系统 cpio.gz
# └── Scripts 安装脚本 cpio.gz
#
# 用法: build_pkg.sh <version> <arch:amd64|arm64> <binary> <outfile>
set -euo pipefail
VERSION="$1"; ARCH="$2"
# xar 与 cpio 都在临时目录里执行,输入输出必须先转成绝对路径
BINARY="$(cd "$(dirname "$3")" && pwd)/$(basename "$3")"
mkdir -p "$(dirname "$4")"
OUTFILE="$(cd "$(dirname "$4")" && pwd)/$(basename "$4")"
case "$ARCH" in
amd64) PKG_ARCH="x86_64" ;;
arm64) PKG_ARCH="arm64" ;;
*) echo "未知架构: $ARCH" >&2; exit 1 ;;
esac
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
ROOT="$WORK/root"
SCRIPTS="$WORK/scripts"
FLAT="$WORK/flat"
PKGDIR="$FLAT/webui4frpc.pkg"
mkdir -p "$ROOT/usr/local/bin" "$ROOT/usr/local/etc/webui4frpc" "$SCRIPTS" "$PKGDIR"
# ---- payload 根文件系统 ----
install -m 0755 "$BINARY" "$ROOT/usr/local/bin/webui4frpc"
cat > "$ROOT/usr/local/etc/webui4frpc/webui4frpc.env" <<'ENVEOF'
# webui4frpc runtime configuration (macOS)
# 请修改密码后再投入使用;改完执行:
# sudo launchctl kickstart -k system/com.jianfeeeee.webui4frpc
W4F_ADDR=0.0.0.0:7500
W4F_USER=admin
W4F_PASSWORD=admin
ENVEOF
chmod 0644 "$ROOT/usr/local/etc/webui4frpc/webui4frpc.env"
# ---- launchd plist ----
mkdir -p "$ROOT/Library/LaunchDaemons"
cat > "$ROOT/Library/LaunchDaemons/com.jianfeeeee.webui4frpc.plist" <<'PLISTEOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jianfeeeee.webui4frpc</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/webui4frpc-launch</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/usr/local/var/log/webui4frpc.log</string>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/webui4frpc.err.log</string>
<key>WorkingDirectory</key>
<string>/usr/local/var/lib/webui4frpc</string>
</dict>
</plist>
PLISTEOF
chmod 0644 "$ROOT/Library/LaunchDaemons/com.jianfeeeee.webui4frpc.plist"
# launchd 不读 EnvironmentFile用小包装脚本 source 配置再 exec
cat > "$ROOT/usr/local/bin/webui4frpc-launch" <<'LAUNCHEOF'
#!/bin/sh
# 读取 /usr/local/etc/webui4frpc/webui4frpc.env 后启动 webui4frpc
set -e
ENV_FILE=/usr/local/etc/webui4frpc/webui4frpc.env
W4F_ADDR=0.0.0.0:7500
W4F_USER=admin
W4F_PASSWORD=admin
[ -f "$ENV_FILE" ] && . "$ENV_FILE"
exec /usr/local/bin/webui4frpc \
-addr "$W4F_ADDR" \
-user "$W4F_USER" \
-password "$W4F_PASSWORD" \
-workdir /usr/local/var/lib/webui4frpc
LAUNCHEOF
chmod 0755 "$ROOT/usr/local/bin/webui4frpc-launch"
# ---- postinstall ----
cat > "$SCRIPTS/postinstall" <<'POSTEOF'
#!/bin/sh
set -e
mkdir -p /usr/local/var/lib/webui4frpc /usr/local/var/log
chmod 750 /usr/local/var/lib/webui4frpc
PLIST=/Library/LaunchDaemons/com.jianfeeeee.webui4frpc.plist
chown root:wheel "$PLIST"
chmod 644 "$PLIST"
# 覆盖安装时先卸载旧的
launchctl bootout system "$PLIST" 2>/dev/null || true
launchctl bootstrap system "$PLIST" 2>/dev/null || \
launchctl load -w "$PLIST" 2>/dev/null || true
exit 0
POSTEOF
chmod 0755 "$SCRIPTS/postinstall"
# ---- Payload / Scripts (cpio.gz) ----
( cd "$ROOT" && find . -print | cpio -o --format odc --owner 0:0 2>/dev/null ) \
| gzip -9 > "$PKGDIR/Payload"
( cd "$SCRIPTS" && find . -print | cpio -o --format odc --owner 0:0 2>/dev/null ) \
| gzip -9 > "$PKGDIR/Scripts"
# ---- Bom ----
mkbom -u 0 -g 80 "$ROOT" "$PKGDIR/Bom"
NFILES=$(find "$ROOT" | wc -l)
INSTALL_KB=$(du -sk "$ROOT" | cut -f1)
# ---- PackageInfo ----
cat > "$PKGDIR/PackageInfo" <<INFOEOF
<?xml version="1.0" encoding="utf-8"?>
<pkg-info format-version="2"
identifier="com.jianfeeeee.webui4frpc"
version="$VERSION"
install-location="/"
auth="root"
relocatable="false"
overwrite-permissions="true">
<payload installKBytes="$INSTALL_KB" numberOfFiles="$NFILES"/>
<scripts>
<postinstall file="./postinstall"/>
</scripts>
<bundle-version/>
</pkg-info>
INFOEOF
# ---- Distribution ----
cat > "$FLAT/Distribution" <<DISTEOF
<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1">
<title>webui4frpc $VERSION</title>
<organization>com.jianfeeeee</organization>
<options customize="never" require-scripts="false" hostArchitectures="$PKG_ARCH"/>
<domains enable_localSystem="true" enable_anywhere="false" enable_currentUserHome="false"/>
<volume-check>
<allowed-os-versions><os-version min="11.0"/></allowed-os-versions>
</volume-check>
<welcome language="zh_CN" mime-type="text/plain">webui4frpc — 可视化 frpc 控制器
安装内容:
/usr/local/bin/webui4frpc 主程序(内嵌 Web 界面)
/usr/local/etc/webui4frpc/webui4frpc.env 配置文件
/Library/LaunchDaemons/…webui4frpc.plist 开机自启服务
安装完成后服务自动启动,访问 http://127.0.0.1:7500
默认凭据 admin/admin —— 请立即修改 webui4frpc.env 中的密码。</welcome>
<choices-outline>
<line choice="default">
<line choice="com.jianfeeeee.webui4frpc"/>
</line>
</choices-outline>
<choice id="default"/>
<choice id="com.jianfeeeee.webui4frpc" visible="false">
<pkg-ref id="com.jianfeeeee.webui4frpc"/>
</choice>
<pkg-ref id="com.jianfeeeee.webui4frpc"
version="$VERSION"
onConclusion="none">#webui4frpc.pkg</pkg-ref>
</installer-gui-script>
DISTEOF
# ---- 打成 xar (Distribution 必须是第一个成员) ----
rm -f "$OUTFILE"
( cd "$FLAT" && xar --compression none -cf "$OUTFILE" Distribution webui4frpc.pkg )
echo "已生成: $OUTFILE ($(du -h "$OUTFILE" | cut -f1))"