
Compile bug: out-of-tree build fails to provision UI assets: ENOENT: no such file or directory, mkdir ‘/src/tools/ui/node_modules’
快速结论:该报错发生在使用 out-of-tree 构建(即源码与构建目录分离)时,同时启用了 LLAMA_BUILD_UI=ON 和 LLAMA_USE_PREBUILT_UI=OFF。优先排查构建系统是否在只读路径下执行 npm install,导致无法创建 node_modules 目录。
问题场景
用户使用 CMake out-of-tree 构建方式编译 llama.cpp,将源代码挂载为只读目录 $srcdir,并在独立的构建目录中运行 cmake 和 make。配置启用了 LLAMA_BUILD_UI=ON 且 LLAMA_USE_PREBUILT_UI=OFF,构建过程中需要从源码目录内的 tools/ui 子目录运行 npm install 以获取 UI 资产,但该目录不可写入。
报错原文
[ 77%] Provisioning UI assets
-- UI: running npm install
-- UI: npm install failed (254)
-- stderr: npm ERR! code ENOENT
npm ERR! syscall mkdir
npm ERR! path /src/tools/ui/node_modules
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, mkdir '/src/tools/ui/node_modules'
原因分析
构建系统在 make 阶段(而非 CMake 配置阶段)触发 UI 资产准备,这会导致以下问题:
- 当源码目录为只读挂载时,构建流程尝试在只读路径
/src/tools/ui/node_modules下执行mkdir(通过npm install),直接失败。 - out-of-tree 构建通常预期所有生成的文件(包括
node_modules)应位于构建目录,但当前构建脚本可能默认将 npm 操作定位到源码目录。
可能原因:构建系统在执行 UI 资产步骤时,未正确处理 out-of-tree 构建环境,未将 node_modules 路径重定向至构建目录;或者源码目录权限不足时,缺少降级机制。该问题已在 PR #24752 中得到修复。
环境排查
- 确认构建方式是否为 out-of-tree(即源代码与构建目录分离)。
- 检查 CMake 配置中
LLAMA_BUILD_UI和LLAMA_USE_PREBUILT_UI的值。 - 确认
tools/ui目录是否位于只读文件系统上(可通过ls -la /src/tools/ui查看挂载状态)。 - 验证
node和npm是否已安装且版本兼容(通常要求 Node.js 16+)。 - 检查报错发生时的工作目录,确认 CMake 是否将
npm install的工作目录设置为了源码目录。
解决步骤
- 首先更新 llama.cpp 至最新提交,确认是否已包含修复 PR #24752(该 PR 修改了 UI 资产构建逻辑以避免只读路径问题)。
- 如果无法更新,可优先尝试设置
LLAMA_USE_PREBUILT_UI=ON以跳过 npm 安装步骤:
cmake -S ${srcdir} -DCMAKE_BUILD_TYPE=Release -DLLAMA_BUILD_UI=ON -DLLAMA_USE_PREBUILT_UI=ON ...
(注意:这需要预先准备 UI 资产,或使用预构建包。) - 另一种可能解法:将源码目录挂载为可读写,或使用 tmpfs 副本,确保
npm install有写权限:
cp -r ${srcdir} /tmp/llama-src && cmake -S /tmp/llama-src ... - 如确定无需 UI,可关闭
LLAMA_BUILD_UI:
cmake ... -DLLAMA_BUILD_UI=OFF - 检查并修复 CMake 中关于
LLAMA_BUILD_SERVER与 UI 的依赖关系,确保 out-of-tree 构建时 npm install 的目标目录指向构建目录内的副本。
验证方法
重新运行 make 直到构建完成,观察 [ 77%] Provisioning UI assets 步骤是否不再报错,且最终成功生成可执行文件(如 llama-server)。可通过 ./llama-server --help 测试 UI 是否正常加载。



