使用分叉Haskell包覆盖nixpkgs时遇到版本不符问题
解决Nix中Haskell分叉包无法在nix-shell中生效的问题
看起来你已经走对了一半——能构建分叉版本说明包的 derivation 是对的,但nix-shell里没拿到正确版本,大概率是Haskell包集覆盖的方式没到位,或者shell环境没正确引用覆盖后的包。我来帮你梳理下问题和修复方案:
问题根源
你当前用super.haskellPackages.override来替换单个包,但这种方式只是简单替换了包本身,没有让整个Haskell包集的依赖解析链都使用你的分叉版本。而且如果shell里没有明确绑定覆盖后的包,nix-shell可能还是会拉取默认nixpkgs里的版本。
修复方案:用overrideScope'替代override
overrideScope'是Nix Haskell包集里专门用来批量/全局覆盖包的工具,它会让所有依赖这个包的其他Haskell包也自动使用你的分叉版本,同时确保shell环境能正确拾取到。
方案1:全局packageOverrides中使用overrideScope'
修改你的shell.nix,把原来的override换成overrideScope',并确保shell明确引用覆盖后的包:
{ nixpkgs ? import <nixpkgs> { config = { packageOverrides = super: { haskellPackages = super.haskellPackages.overrideScope' (self: super: { # 替换成你的分叉包路径 persistent = self.callPackage ../persistent/persistent/persistent.nix {}; }); }; }; } in nixpkgs.mkShell { # 明确引用覆盖后的persistent包 buildInputs = [ nixpkgs.haskellPackages.persistent ]; # 可选:加入ghc,确保shell里的ghc能识别这个包 nativeBuildInputs = [ nixpkgs.haskellPackages.ghc ]; }
方案2:直接在shell中定义自定义Haskell包集
如果不想修改全局config,也可以直接在shell里单独定义覆盖后的包集,更直观:
{ nixpkgs ? import <nixpkgs> {} } let # 构建自定义Haskell包集,覆盖persistent myHaskellPackages = nixpkgs.haskellPackages.overrideScope' (self: super: { persistent = self.callPackage ../persistent/persistent/persistent.nix {}; }); in nixpkgs.mkShell { # 使用自定义包集里的persistent buildInputs = [ myHaskellPackages.persistent ]; # 加入ghc和必要的工具 nativeBuildInputs = [ myHaskellPackages.ghc myHaskellPackages.cabal-install ]; }
验证是否生效
进入nix-shell后,运行以下命令确认版本:
ghc-pkg list persistent
输出里应该能看到你的分叉版本路径,而不是nixpkgs默认的版本。如果用cabal,也可以运行cabal v2-build来验证项目是否使用了你的分叉包。
额外检查点
- 确保
../persistent/persistent/persistent.nix路径是正确的(相对于shell.nix的位置),最好用绝对路径测试下 - 你的
persistent.nix应该是用cabal2nix生成的,手动写的derivation可能会有依赖缺失的问题
内容的提问来源于stack exchange,提问作者Jezen Thomas
相关产品推荐
相关产品推荐

