mcpp toolchain install llvm 依赖包(libxml2, zlib, glibc 等)安装成功,但 LLVM 本体(800MB)缺失:
~/.mcpp/registry/data/xpkgs/
├── xim-x-libxml2/ ✓ 安装成功
├── xim-x-zlib/ ✓ 安装成功
├── xim-x-glibc/ ✓ 安装成功
├── xim-x-llvm/ ✗ 不存在
platform/process.cppm:79-84 的 seal_stdin() 对所有 POSIX 命令追加 </dev/null。
这个修复解决了 macOS 首次运行卡住的问题,但副作用是:xlings 内部的子进程(如解压 800MB LLVM 的 tar 进程)可能依赖 stdin 进行进程间通信或信号传递。小包(libxml2 等)不受影响,大包(LLVM)因为解压时间长,子进程链更复杂,可能被 broken stdin 导致静默失败。
xlings.cppm:432-434 构建的命令:
cd ~/.mcpp && ... xlings interface install_packages --args '...' 2>/dev/null </dev/nullstderr 被完全丢弃。如果 xlings 安装 LLVM 时输出了错误信息到 stderr,我们完全看不到。
xlings.cppm:645-692 的 handle_line 回调:
if (kind != "data") return; // 忽略非 data 事件
if (ls.find_str("dataKind") != "download_progress") return; // 只关心下载进度如果 xlings 发出了 error 事件或 log 事件报告安装失败,全部被静默丢弃。
package_fetcher.cppm:608-638 有一个 Windows-only 的 workaround:
#if defined(_WIN32)
// 如果 verdir 不存在,检查全局 xlings 目录 ~/.xlings/data/xpkgs/ 并复制过来
if (!std::filesystem::exists(verdir)) {
// ... copy from ~/.xlings/ to ~/.mcpp/
}
#endif这个 workaround 处理了 "xlings 把包装到全局目录而非 XLINGS_HOME 指定目录" 的情况。Linux 没有这个 fallback。
CI 设置了 MCPP_VENDORED_XLINGS="$XLINGS_BIN":
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
"$MCPP" build --target x86_64-linux-muslMCPP_VENDORED_XLINGS 触发 make_xlings_env() 中的特殊路径,使用全局 xlings 二进制。而且 CI 中的工具链安装走的是 xlings 全局 sandbox(因为 MCPP_HOME 显式设置),与用户本地的嵌套沙箱场景完全不同。
实际上 CI 也没有测试 mcpp toolchain install llvm 这个用户流程——CI 只测试 mcpp build(使用预装的工具链)。
Windows 已经用直接 xlings install ... -y 命令而非 interface 模式。Linux 也应该如此:
int install_with_progress(const Env& env, std::string_view target,
const BootstrapProgressCallback& cb)
{
// 所有平台统一:先用直接命令安装
auto directCmd = build_command_prefix(env) + std::format(" install {} -y", target);
int directRc = mcpp::platform::process::run_silent(directCmd);
if (directRc == 0) return 0;
// 直接命令失败则 fallback 到 interface 模式(保留进度回调能力)
// ...
}在 resolve_xpkg_path() 中,将 Windows 的全局目录 fallback 扩展到所有平台:
// 移除 #if defined(_WIN32),改为所有平台通用
if (!std::filesystem::exists(verdir)) {
// 检查全局 xlings 目录
auto homeDir = std::getenv("HOME");
if (homeDir) {
std::filesystem::path globalXpkgs =
std::filesystem::path(homeDir) / ".xlings" / "data" / "xpkgs";
auto globalVerdir = globalXpkgs / verdir.filename().parent_path().filename() / verdir.filename();
if (std::filesystem::exists(globalVerdir)) {
// 复制或软链接到 sandbox
}
}
}为 install_with_progress() 添加不关闭 stdin 的选项,或让直接 install 命令走 std::system() 而非 platform::process:
// 直接命令不通过 platform::process(不追加 </dev/null)
int directRc = std::system(directCmd.c_str());在 ci.yml 中增加专门测试 mcpp toolchain install llvm 的步骤,确保这个用户核心流程被覆盖。
- 修复 1 + 修复 3:Linux 改用直接命令 + 不关闭 stdin(最可能解决问题)
- 修复 2:增加全局目录 fallback(兜底)
- 修复 4:增加 CI 测试(防止回归)