解决Nix Derivation报错:unpacker produced multiple directories
解决Nix Build中"unpacker produced multiple directories"错误
问题原因
Nix默认的unpackPhase会自动解压源码包,并要求解压后的内容只有一个顶级目录。但你的jdtls压缩包根目录直接包含plugins、bin、config_linux等多个顶级目录,违反了这个默认规则,因此触发错误。
解决方案
有两种常用的修复方式,任选其一即可:
方案1:禁用默认解压阶段,手动处理解压
直接跳过Nix的默认unpackPhase,在buildPhase里自己完成解压和目录整理:
{ stdenv, fetchurl, gnutar, ... }: stdenv.mkDerivation { pname = "jdtls"; version = "1.28.0"; src = fetchurl { url = "https://www.eclipse.org/downloads/download.php?file=/jdtls/snapshots/jdt-language-server-1.28.0-202309211406.tar.gz"; sha256 = "q9O44I8iLuNT/eD1IDVnoa1TQgzEIhl2YF40wD0y/sA="; }; nativeBuildInputs = [ gnutar ]; # 禁用默认的自动解压逻辑 dontUnpack = true; buildPhase = '' # 创建jdtls的主存储目录 mkdir -p $out/share/jdtls # 将压缩包内容完整解压到目标目录 tar -xf $src -C $out/share/jdtls # 把可执行文件链接到全局bin目录,方便直接调用 mkdir -p $out/bin ln -s $out/share/jdtls/bin/jdtls $out/bin/jdtls ''; }
方案2:自定义解压命令,统一放到单个目录
保留默认的unpackPhase,但自定义解压命令,让所有内容都解压到一个子目录下,满足Nix的检查要求:
{ stdenv, fetchurl, gnutar, ... }: stdenv.mkDerivation { pname = "jdtls"; version = "1.28.0"; src = fetchurl { url = "https://www.eclipse.org/downloads/download.php?file=/jdtls/snapshots/jdt-language-server-1.28.0-202309211406.tar.gz"; sha256 = "q9O44I8iLuNT/eD1IDVnoa1TQgzEIhl2YF40wD0y/sA="; }; nativeBuildInputs = [ gnutar ]; # 自定义解压命令,将所有内容放到source/jdtls目录下 unpackCmd = '' mkdir -p source/jdtls tar -xf $src -C source/jdtls ''; buildPhase = '' # 将解压后的内容复制到输出目录 cp -r source/jdtls/* $out/share/jdtls # 链接可执行文件到全局bin目录 mkdir -p $out/bin ln -s $out/share/jdtls/bin/jdtls $out/bin/jdtls ''; }
额外说明
两种方案都完成了以下核心操作:
- 完整保留jdtls的所有目录结构(包括平台相关的config目录)
- 将可执行文件链接到
$out/bin,确保安装后可以直接通过jdtls命令调用服务
内容的提问来源于stack exchange,提问作者s1n7ax
相关产品推荐
相关产品推荐

