装个终端而已:8GB 的 Xcode 下成了 82K 的 HTML,我差点抹掉一块有数据的 2TB 硬盘

图片

今天想装一个开源终端,叫 Zap(Warp 的分叉,本地优先、自带 AI Agent)。

最后装成了,cargo check 0 错误,App 611 MB,跑起来了。但中间我差一点做了两件蠢事:升级操作系统,以及抹掉一块装着我数据的 2TB 硬盘

而这一切的起因,是缺一个编译器。终点是——我只需要在浏览器里勾一个复选框。

这篇不是安装教程,是决策滑坡的复盘。技术坑我会写,但真正值钱的是中间那段”我怎么一步步跑偏的”。


一、起点:一个 Metal 编译器

cargo check 跑了几分钟,倒在这里:

thread ‘main’ panicked at crates/warpui/build.rs:92:5:
error compiling metal shaders to .air;
xcrun: error: unable to find utility “metal”, not a developer tool or in PATH

这个项目自研了 UI 框架,macOS 上走 Metal 渲染,构建时要把 .metal 着色器编译成 .metallib

问题是:metal 编译器只随完整版 Xcode 分发。命令行工具(Command Line Tools)里没有,Apple 也不提供单独下载。

我机器上只有 CLT,没有 Xcode。于是去 App Store:

不能将 Xcode 安装在”Macintosh HD”上,因为需要 macOS v26.2 或更高版本。

我的系统是 macOS 15.7.3。App Store 的 Xcode 已经是 26.2 了。

第一个岔路口出现了。


二、滑坡:我是怎么从”装终端”走到”抹硬盘”的

复盘时把这条链子画出来,很清楚:

想装 zap
└─ 需要 Xcode
└─ App Store 版要 macOS 26
└─ 升级系统需要备份
└─ 备份需要空盘
└─ 唯一的盘有数据 ← 我在这里

每一步单独看都合理。合起来看,我为了装一个终端,正准备升级操作系统。

图片

第一次刹车

其实有另一条路:Xcode 16.4 支持 macOS 15.3+,从 developer.apple.com 下载就行,不用升级系统。

我一开始选了这条。然后撞上 403:

Received 403: Unauthorized. This can happen when either:

  1. Apple Developer Terms and Conditions were not accepted
  2. Apple ID authorization was revoked for some other reason

这个 Apple ID 从没在开发者网站用过,没接受过开发者协议。

就是这个 403,让我说出了”我打算更新系统好了”。

现在回头看很荒谬:接受开发者协议是免费的、30 秒的、一个复选框。而我因为它,准备去做一件 1-2 小时、不可逆、需要先做全量备份的事。

第二次刹车

决定升级后,先查备份状态:

tmutil destinationinfo → No destinations configured.
tmutil latestbackup → Failed to mount destination.

Time Machine 从未配置过。一次备份都没有。 431 GB 数据裸奔。

macOS 大版本升级没有回滚路径。想退回 15.7.3 只能抹盘重装,然后从零重建整个环境——brew 的 5 个 tap、nvm、pnpm、composer、cargo、各种 dotfiles、钥匙串里所有凭据。

那就先备份。查了下已连接的设备:

设备 情况
2 TB Seagate Portable 容量够
32 GB U 盘 只剩 12 GB

2TB 那块看起来完美。但 diskutil info 显示 File System: None,没挂载。

差一点就格式化了。

Time Machine 要求 APFS 或 HFS+,用这块盘就得抹掉整盘。看着像空盘,很容易就 diskutil eraseDisk 下去了。

先查了一下:

#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *2.0 TB disk4
1: Windows_NTFS Seagate Portable Drive 2.0 TB disk4s1

NTFS,一整个分区,里面是我的数据。(没挂载只是因为 macOS 对 NTFS 的支持问题,不是空盘。)

我把这个结果发出去,回复是:「有我数据啊 晕死」。


三、那个 82K 的”Xcode”

后来老老实实回去点了复选框,xcodes install 16.4 跑起来。然后:

(1/6) Found existing archive that will be used for installation at
…/Xcode-16.4.0+16F6.xip
(2/6) Unarchiving Xcode (This can take a while)
Unxip/Unxip.swift:492: Precondition failed
[1] 61446 trace trap

解压器崩了。第一反应是 --experimental-unxip 这个实验性标志不稳。

但看了眼文件大小——

-rw-r–r– 82K Xcode-16.4.0+16F6.xip

82K。完整的 Xcode 是 8 GB。

$ file Xcode-16.4.0+16F6.xip
HTML document text, Unicode text, UTF-8 text

$ head -c 400 Xcode-16.4.0+16F6.xip

Unauthorized - Apple Developer

是之前那次 403 的错误页面,被当成 .xip 存下来了。

aria2 把 HTTP 错误响应的 HTML 正文当作文件内容写进了磁盘。然后 xcodes 看到文件存在,报告”Found existing archive”,直接拿这坨 HTML 去解压。

这个坑很阴——它不报下载失败,它报解压失败。如果不去看文件大小,很容易一直在解压器上折腾。

删掉重下,8 GB 正常到位。


四、三个真实的技术坑

抛开决策失误,纯技术层面卡了三次:

1. Metal 编译器(需要完整 Xcode)

crates/warpui/build.rs 里无条件调用:

if env::var(“CARGO_CFG_TARGET_OS”).as_deref() == Ok(“macos”) {
bindgen_shader_types();
compile_metal_shaders(); // ← 这里
compile_objc_lib();
}

没有开关能跳过。CLT 不含 metal,必须装 Xcode。

附带发现script/macos/install_build_deps 里有一行 xcodebuild -downloadComponent MetalToolchain。Xcode 16.4 不需要这步(Metal 工具链内置),拆成独立下载组件是 Xcode 26+ 才有的变化。

验证编译器能用,可以直接跑 build.rs 里的原始命令,几秒钟出结果:

xcrun -sdk macosx metal -c
crates/warpui/src/platform/mac/rendering/metal/shaders/shaders.metal
-o /tmp/test.air

2. 伪装成 .xip 的 HTML 错误页

见上一节。教训:解压失败先看文件大小。

3. protoc 缺失

Could not find protoc. … To install it on macOS, run brew install protobuf
error: failed to run custom build command for warp_multi_agent_api

brew install protobuf 解决。

值得一提的是,官方的 script/macos/bootstrap没有 protobuf——它装了 jq、clang-format、create-dmg、multitime、powershell、pkgconf、llvm,唯独漏了这个。脚本开头自己写着 “This script is a work in progress, and may be incomplete”,确实诚实。


五、最终环境

组件 版本
macOS 15.7.3(没有升级
Xcode 16.4 (16F6)
Rust 1.92.0(rust-toolchain.toml 锁定)
protoc 35.1
cargo-bundle 0.5.1(仓库锁定的 fork)

构建结果:0 错误,2 个 warning(都是上游既有的)。产物 Zap.app 611 MB,二进制 609 MB,ad-hoc 签名(没有开发者证书也能跑)。

完整流程:

1. 装 Xcode 16.4(需要在真实终端里跑,验证码要 TTY)

brew install aria2 # 下载加速,可选
xcodes install 16.4 –empty-trash –select

2. 补依赖

brew install protobuf
cargo install binstall@1.14.3"">cargo-binstall@1.14.3 –locked
cargo binstall -y diesel_cli cargo-nextest
cargo install cargo-bundle
–git=github.com/burtonageo/cargo-bundle
–rev ae4c76e92c08774bf54ff077b1c52e3d1cd6c16d

3. 构建并启动

cargo check # 验证
./script/run # 打包成 .app 并运行

有个细节:xcodes install必须在真实终端窗口里跑。Apple ID 的双重验证码需要 TTY,任何非交互环境(包括 AI 助手的命令执行)都拿不到输入。


六、复盘:我到底错在哪

技术坑不算错,那是必然要踩的。真正的错误是决策链。

错误一:被小阻塞推着做大决定

403 是一个 30 秒的问题。我的反应是升级操作系统。

这种情况有个特征:你不是在评估方案,你是在逃避当前的挫败感。 判断标准很简单——把成本摆出来对比一下:

  • 方案 A:点一个复选框,30 秒,零风险

  • 方案 B:升级系统 1-2 小时 + Xcode 15 GB + 不可逆 + 需要先做全量备份

写出来就很明显了。但在被 403 卡住的当下,B 看起来更”干脆”。

错误二:没有备份,却在做不可逆操作

431 GB 数据,零备份,准备升级操作系统。

我甚至不知道自己没有备份,是查了 tmutil 才发现的。

错误三:差点对”看起来是空盘”的盘动手

File System: None + 没挂载 = 看起来像空盘。实际是 NTFS,装着数据。

动盘之前先 diskutil list 这个成本是 2 秒,代价是 2 TB。


七、装完之后怎么用

日常启动不用重新构建:

open ~/Code/zap/target/debug/bundle/osx/Zap.app

改了代码之后再走完整流程:

cd ~/Code/zap && ./script/run

但注意:上面装出来的是 debug 构建,未优化。终端模拟器对延迟敏感,debug 版滚动和渲染会明显发钝。日常用的话建议编译 release 版

./script/run –release –dont-open
cp -R target/release/bundle/osx/Zap.app /Applications/

放进 /Applications 之后就能 Spotlight 搜索、锁到 Dock,跟正常 App 一样用。代价是以后更新代码要重新执行这两步。


最后

一个终端软件,从”想装”到”跑起来”,中间隔着一个 Metal 编译器、一个 8 GB 的 Xcode、一个 82 K 的 HTML 错误页,和两次差点走偏的决策。

技术问题都有解。难的是在被卡住的时候,还能停下来算一次成本。

顺带一提,那块 2TB 硬盘全程只做了只读探查,数据完好。但”这台机器一次备份都没有”这件事,独立于今天的任务存在——它值得单独处理一次,而不是被一个编译错误逼出来的紧急决定。

本人项目地址:github.com/xaiwind/warp-zap-ailap 基于warp-zap 做了些改动,mac本地实测可用。
以上文章由claude code 根据工作记录生成 ,本人审核负责。如果文章对你有一点帮助,欢迎点赞、评论、收藏关!注我是想风,@xaiwind 一个关注出海与 AI 的创作者。
本文首发想风技术文档

本作品采用《CC 协议》,转载必须注明作者和本文链接
唯有坚持,滴水穿石----will
zhaocrazy
讨论数量: 2

一个悲剧写成了喜剧效果

2天前 评论
zhaocrazy (楼主) 2天前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
编程AI 出海 @ 数字游民
文章
86
粉丝
29
喜欢
69
收藏
152
排名:502
访问:1.7 万
私信
所有博文