Haskell Stack重启后重复下载依赖问题(NixOS环境)
我之前在NixOS上用Stack开发Haskell项目时也遇到过一模一样的问题——每次重启后首次运行stack ghci都要重新拉一堆系统依赖,慢得让人抓狂。结合我踩过的坑,给你几个针对性的解决方案:
1. 让Stack深度集成Nix,复用Nix的包缓存
NixOS的包管理基于只读的/nix/store,但Stack默认行为没有和Nix的缓存机制打通,导致每次重启后Stack无法识别之前下载的Nix包,只能重新拉取。解决办法是在Stack配置里启用Nix集成:
项目级配置(仅针对montevideo项目)
打开项目根目录的stack.yaml,添加或修改以下内容:
# 用对应GHC 8.8.3的resolver,lts-16.31正好匹配这个版本,能解决版本兼容警告 resolver: lts-16.31 nix: enable: true # 提前声明你需要的系统依赖,Stack会让Nix预先准备好这些包 packages: - glpk - pcre # 关闭pure模式,让Stack能访问系统已有的Nix缓存,避免重复构建 pure: false
全局配置(所有项目生效)
如果不想每个项目都改,编辑~/.stack/config.yaml,添加:
nix: enable: true
2. 解决版本兼容警告
你遇到的Stack与GHC 8.8.3、Cabal 3.0.1.0不兼容警告,核心是Stack的resolver版本和你使用的GHC/Cabal版本不匹配。上面指定的lts-16.31 resolver正好对应GHC 8.8.3和Cabal 3.0.1.0,配置后这个警告应该会消失。
3. 优化Nix二进制缓存,加速下载速度
确保Nix使用官方二进制缓存,避免本地编译耗时。编辑/etc/nix/nix.conf(需要sudo权限),添加或确认以下配置:
substituters = https://cache.nixos.org/ trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
这样Nix会优先从官方缓存下载预编译的二进制包,而不是从头编译,能把构建时间从几分钟压缩到几十秒。
4. 修复Cabal文件语法警告
这个警告是因为你的.cabal文件用了过时的语法。比如检查是否有废弃的字段(比如custom-setup的旧写法),或者字段格式不符合Cabal 3.0的规范。你可以参考LTS 16.x对应的Cabal文档,把.cabal文件里的语法更新到对应版本的要求。
验证效果
配置完成后,第一次运行stack ghci --ghci-options -Wall可能还是需要下载依赖(因为要初始化Nix环境),但重启电脑后再次运行,Stack会直接复用/nix/store里已有的包,不会重复下载,构建速度也会快很多。
内容的提问来源于stack exchange,提问作者Jeffrey Benjamin Brown

