Nix打包libmonome遇waf写入目录错误求助
解决Nix打包libmonome(waf构建)的只读目录报错问题
嘿,我刚好碰到过类似的waf在Nix里构建的坑,帮你梳理下怎么搞定这个libmonome的打包问题!
首先咱们先抓核心矛盾:waf构建工具默认会把自身的内部库解压到当前源码目录或者系统路径,但Nix的构建沙箱里,除了临时目录和最终输出目录$out,其他全是只读状态——这就是你看到“无法将waf库解压到/nix/store只读目录”的根本原因。另外你加的sudo完全多余,Nix构建不需要权限,而且沙箱里也压根没sudo权限。
关键修复步骤拆解
1. 改用Nix标准的mkDerivation而非底层derivation
直接用derivation太原始了,stdenv.mkDerivation已经封装了PATH自动处理、沙箱配置、临时目录管理等一堆细节,能省超多手动配置的麻烦。
2. 正确拉取带子模块的源码
你之前fetchGit失败,是因为没开启子模块拉取——libmonome的源码依赖子模块,必须加上submodules = true参数才能拉全代码。
3. 给waf指定可写的临时目录
waf需要一个可写的地方解压自身的库文件,咱们可以通过设置WAFDIR环境变量,指向Nix构建时自带的临时目录$TMPDIR,这个目录是完全可写的。
完整的工作配置
default.nix
{ pkgs ? import <nixpkgs> {} }: pkgs.stdenv.mkDerivation rec { pname = "libmonome"; version = "unstable-2024-05-20"; # 可根据需要调整版本标识 src = pkgs.fetchGit { url = "https://github.com/monome/libmonome.git"; rev = "c20581f839f8e0fb39b2762baeea7d0a7ab10783"; # 你指定的commit submodules = true; # 核心:拉取所有依赖子模块 fetchSubmodules = true; # 部分Nix版本需要这个参数配合 }; # 只保留必要依赖,mkDerivation会自动包含git、coreutils等基础工具 buildInputs = with pkgs; [ liblo python2 ]; buildPhase = '' # 让waf把内部库解压到临时可写目录 export WAFDIR=$TMPDIR # 配置时明确指定安装路径为Nix的输出目录$out python2 ./waf configure --prefix=$out # 执行构建 python2 ./waf build ''; installPhase = '' # 直接安装到$out,不需要sudo python2 ./waf install ''; meta = with pkgs.lib; { description = "用于控制monome硬件的工具包(带LED的OSC音乐控制器)"; homepage = "https://monome.org/"; license = licenses.gpl3; platforms = platforms.linux; # 根据libmonome支持的平台调整 }; }
为什么之前的配置会失败?
- 直接用
derivation没有利用Nix的标准构建环境,手动设置PATH容易遗漏或出错; fetchGit没开启子模块拉取,导致源码依赖缺失;- waf默认在只读的源码目录解压自身库,设置
WAFDIR到临时目录解决了写入权限问题; - 用
sudo完全没必要,Nix构建会将文件安装到$out目录,这个目录是构建过程中可写的。
调试小技巧
如果还有问题,可以用nix-build -K命令构建,失败后会保留临时构建目录,你可以进去查看详细日志和文件状态,方便排查问题。
内容的提问来源于stack exchange,提问作者Jeffrey Benjamin Brown
相关产品推荐
相关产品推荐

