为何Nix SQLite覆盖层会触发Python 3.10包重新编译?
问题分析与解决
为什么会触发Python生态重编译?
Nix的构建系统基于纯函数模型,所有包的构建结果由其输入的哈希值唯一确定。当你通过覆盖层全局修改sqlite的configureFlags时,sqlite的输出哈希会发生变化。而sqlite是很多Python包(比如python3.10-cffi)的依赖项,这些包的构建输入包含sqlite的输出哈希,因此它们会被标记为需要重新构建,最终导致大量Python生态包被重新编译。
你尝试用sqlite.override (_: { python3Packages = {}; })剔除输入无效,是因为这个操作只是修改了sqlite自身的构建依赖(比如用于测试的Python工具),但下游Python包依赖的是sqlite的最终输出结果——只要sqlite的输出哈希变了,下游依赖就会触发重建,和sqlite自身的构建依赖无关。
解决办法:避免全局覆盖sqlite
不要通过覆盖层全局修改sqlite,而是在devShell中单独构建一个带有自定义编译标志的sqlite实例,这样不会影响全局依赖链,也就不会触发大量重编译。修改你的flake.nix中devShells部分如下:
devShells.x86_64-linux.default = pkgs.mkShell { buildInputs = [ # 单独构建带动态扩展的sqlite,仅在当前devShell中生效 (pkgs.sqlite.overrideAttrs (oldAttrs: { configureFlags = oldAttrs.configureFlags ++ ["--enable-dynamic-extensions"]; })) ]; };
这样只会构建这个自定义的sqlite包,全局的sqlite保持不变,依赖全局sqlite的Python包不需要重新编译,你也能在devShell中使用带动态扩展的sqlite。
内容的提问来源于stack exchange,提问作者Vey
相关产品推荐
相关产品推荐

