forked from imj01y/trace-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·316 lines (273 loc) · 8 KB
/
build.sh
File metadata and controls
executable file
·316 lines (273 loc) · 8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#!/usr/bin/env bash
#
# trace-ui 跨平台构建脚本
# 支持 Windows (MSYS/Git Bash), macOS, Linux
#
# 用法:
# ./build.sh dev # 开发模式(Vite HMR + Rust 热重载)
# ./build.sh debug # 构建 debug 版本
# ./build.sh release # 构建 release 版本(LTO 优化)
# ./build.sh bundle # 打包安装程序(.msi / .dmg / .deb)
# ./build.sh clean # 清理所有构建产物
#
set -euo pipefail
# ── 颜色输出 ──
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
title() { echo -e "\n${BOLD}═══ $* ═══${NC}"; }
# ── 项目根目录 ──
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
WEB_DIR="src-web"
# ── 平台检测 ──
detect_platform() {
local uname_s
uname_s="$(uname -s)"
case "$uname_s" in
MINGW*|MSYS*|CYGWIN*|Windows_NT)
PLATFORM="windows"
BINARY_EXT=".exe"
BUNDLE_TYPE="msi"
;;
Darwin)
PLATFORM="macos"
BINARY_EXT=""
BUNDLE_TYPE="dmg"
;;
Linux)
PLATFORM="linux"
BINARY_EXT=""
BUNDLE_TYPE="deb"
;;
*)
err "不支持的平台: $uname_s"
exit 1
;;
esac
info "平台: ${BOLD}$PLATFORM${NC} ($uname_s)"
}
# ── 依赖检查 ──
check_deps() {
title "检查依赖"
local missing=0
if command -v node &>/dev/null; then
ok "node $(node --version)"
else
err "未找到 node,请安装 Node.js"; missing=1
fi
if command -v npm &>/dev/null; then
ok "npm $(npm --version)"
else
err "未找到 npm"; missing=1
fi
if command -v cargo &>/dev/null; then
ok "cargo $(cargo --version | awk '{print $2}')"
else
err "未找到 cargo,请安装 Rust"; missing=1
fi
if command -v cargo-tauri &>/dev/null || cargo tauri --version &>/dev/null 2>&1; then
ok "cargo-tauri $(cargo tauri --version 2>/dev/null | awk '{print $2}' || echo '已安装')"
else
warn "未找到 cargo-tauri,bundle 命令不可用(安装: cargo install tauri-cli)"
fi
if [[ $missing -ne 0 ]]; then
err "缺少必要依赖,请先安装后重试"
exit 1
fi
}
# ── 前端构建 ──
build_frontend() {
title "构建前端"
cd "$SCRIPT_DIR/$WEB_DIR"
if [[ ! -d node_modules ]]; then
info "安装 npm 依赖..."
npm install
fi
info "构建前端(tsc + vite)..."
npm run build
ok "前端构建完成 → $WEB_DIR/dist/"
cd "$SCRIPT_DIR"
}
# ── Rust 构建 ──
build_rust() {
local mode="$1" # debug | release
title "构建 Rust ($mode)"
cd "$SCRIPT_DIR"
if [[ "$mode" == "release" ]]; then
cargo build --release --features custom-protocol
local bin="target/release/trace-ui${BINARY_EXT}"
else
cargo build --features custom-protocol
local bin="target/debug/trace-ui${BINARY_EXT}"
fi
if [[ -f "$bin" ]]; then
local size
size=$(du -h "$bin" | cut -f1)
ok "Rust 构建完成 → $bin ($size)"
else
err "构建产物未找到: $bin"
exit 1
fi
# macOS: 创建 .app Bundle 以避免启动时弹出终端
if [[ "$PLATFORM" == "macos" ]]; then
create_macos_app "$bin" "$mode"
fi
}
# ── macOS .app Bundle 生成 ──
create_macos_app() {
local bin="$1"
local mode="$2"
local app_name="Trace UI.app"
local app_dir="target/$mode/$app_name"
info "创建 macOS App Bundle..."
mkdir -p "$app_dir/Contents/MacOS"
mkdir -p "$app_dir/Contents/Resources"
# 复制二进制文件
cp -f "$bin" "$app_dir/Contents/MacOS/trace-ui"
# 复制图标
if [[ -f "icons/icon.icns" ]]; then
cp -f "icons/icon.icns" "$app_dir/Contents/Resources/icon.icns"
fi
# 从 tauri.conf.json 读取版本号
local app_version
app_version=$(grep '"version"' tauri.conf.json | head -1 | sed 's/.*"\([0-9][0-9.]*\)".*/\1/')
info "App version: $app_version"
# 生成 Info.plist
cat > "$app_dir/Contents/Info.plist" << PLIST
<?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>CFBundleExecutable</key>
<string>trace-ui</string>
<key>CFBundleIdentifier</key>
<string>com.ai-trace.trace-ui</string>
<key>CFBundleName</key>
<string>Trace UI</string>
<key>CFBundleDisplayName</key>
<string>Trace UI</string>
<key>CFBundleVersion</key>
<string>${app_version}</string>
<key>CFBundleShortVersionString</key>
<string>${app_version}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>icon</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
PLIST
# Ad-hoc 签名(ARM64 macOS 强制要求,否则内核直接 SIGKILL)
info "签名 App Bundle (ad-hoc)..."
codesign --force --deep --sign - "$app_dir"
ok "App Bundle 创建完成 → $app_dir"
info "启动方式: open \"$app_dir\""
}
# ── Tauri 打包 ──
build_bundle() {
title "打包安装程序 ($BUNDLE_TYPE)"
cd "$SCRIPT_DIR"
if ! cargo tauri --version &>/dev/null 2>&1; then
err "需要 cargo-tauri CLI(安装: cargo install tauri-cli)"
exit 1
fi
cargo tauri build
ok "打包完成,产物位于 target/release/bundle/"
cd "$SCRIPT_DIR"
}
# ── 清理 ──
do_clean() {
title "清理构建产物"
info "清理 Rust 产物..."
cargo clean
if [[ -d "$WEB_DIR/dist" ]]; then
info "清理前端产物..."
rm -rf "$WEB_DIR/dist"
fi
if [[ -d "$WEB_DIR/node_modules" ]]; then
read -rp "是否删除 node_modules?[y/N] " answer
if [[ "$answer" =~ ^[Yy]$ ]]; then
rm -rf "$WEB_DIR/node_modules"
ok "node_modules 已删除"
fi
fi
ok "清理完成"
}
# ── 开发模式 ──
do_dev() {
title "启动开发模式"
cd "$SCRIPT_DIR"
if [[ ! -d "$SCRIPT_DIR/$WEB_DIR/node_modules" ]]; then
info "安装 npm 依赖..."
cd "$SCRIPT_DIR/$WEB_DIR"
npm install
cd "$SCRIPT_DIR"
fi
info "启动 cargo tauri dev(Vite HMR + Rust 热重载)..."
cargo tauri dev
}
# ── 主流程 ──
main() {
local cmd="${1:-help}"
local start_time
start_time=$(date +%s)
detect_platform
case "$cmd" in
dev)
check_deps
do_dev
;;
debug)
check_deps
build_frontend
build_rust debug
;;
release)
check_deps
build_frontend
build_rust release
;;
bundle)
check_deps
build_frontend
build_bundle
;;
clean)
do_clean
;;
help|--help|-h)
echo "用法: $0 <command>"
echo ""
echo "命令:"
echo " dev 开发模式(Vite HMR + Rust 热重载)"
echo " debug 构建 debug 版本"
echo " release 构建 release 版本(LTO 优化)"
echo " bundle 打包安装程序(.msi / .dmg / .deb)"
echo " clean 清理所有构建产物"
exit 0
;;
*)
err "未知命令: $cmd"
echo "运行 $0 help 查看可用命令"
exit 1
;;
esac
local end_time elapsed
end_time=$(date +%s)
elapsed=$((end_time - start_time))
echo ""
ok "完成!耗时 ${elapsed}s"
}
main "$@"