如何将buildPythonPackage构建的Nix包导入mach-nix环境
解决方案
你遇到的依赖冲突报错,核心原因有两点:
- 你在
requirements中声明了artiq,触发mach-nix从内置依赖数据库匹配包元数据,但第三方flake构建的artiq不在mach-nix的pypi/nixpkgs依赖索引中,直接触发冲突。 - 你使用
overridesPre注入外部包的时机不对,该阶段在mach-nix完成依赖解析前执行,注入的包不会被识别为已满足的依赖项。
方案一:Override注入(无依赖冲突,推荐)
按以下步骤修改配置即可:
- 从
requirements文本中删除artiq项,避免mach-nix尝试解析这个外部包。 - 改用
overridesPost注入外部构建的artiq包,在override中补全配置,让mach-nix复用已安装的公共依赖,不重复构建。 - 显式指定mach-nix使用和artiq构建时完全一致的Python版本,避免二进制不兼容问题。
修正后的可运行配置示例:
{ inputs = { nixpkgs.follows = "artiq/nixpkgs"; artiq.url = "github:m-labs/artiq"; mach-nix.url = "mach-nix"; }; outputs = { self , artiq , nixpkgs , mach-nix }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; # 复用artiq构建时绑定的Python版本,保证ABI兼容 targetPython = artiq.packages.x86_64-linux.artiq.python; artiqInject = self: super: { artiq = artiq.packages.x86_64-linux.artiq.overridePythonAttrs (old: { dontBuild = true; doCheck = false; # 将artiq的依赖替换为mach-nix环境中已安装的同包名版本,避免重复安装 propagatedBuildInputs = builtins.map (dep: if builtins.hasAttr dep.pname self then self.${dep.pname} else dep ) old.propagatedBuildInputs; }); }; in rec { inherit pkgs; devShells.x86_64-linux.default = pkgs.mkShell { name = "artiq-environment"; buildInputs = [ (mach-nix.lib.x86_64-linux.mkPython { python = targetPython; # 此处不要写artiq,仅列公共PyPI依赖 requirements = '' numpy pip # 补充artiq依赖的其他公共包,如python-dateutil、pyqtgraph等 ''; overridesPost = [ artiqInject ]; }) ]; }; }; }
如果运行时提示缺少依赖,只需要把对应缺失的公共包名加到requirements中,mach-nix会自动解析安装,override逻辑会自动完成依赖对齐。
方案二:直接并列引入(配置简单,适合依赖少的场景)
如果不想写override逻辑,可以直接把外部构建的artiq作为buildInputs的平级项,和mach-nix生成的Python环境并列放入mkShell,mkShell会自动把所有Python包路径加入PYTHONPATH,只要Python版本一致即可正常导入。
配置示例:
{ inputs = { nixpkgs.follows = "artiq/nixpkgs"; artiq.url = "github:m-labs/artiq"; mach-nix.url = "mach-nix"; }; outputs = { self , artiq , nixpkgs , mach-nix }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; targetPython = artiq.packages.x86_64-linux.artiq.python; in rec { inherit pkgs; devShells.x86_64-linux.default = pkgs.mkShell { name = "artiq-environment"; buildInputs = [ # 直接引入外部构建的artiq artiq.packages.x86_64-linux.artiq (mach-nix.lib.x86_64-linux.mkPython { python = targetPython; requirements = '' numpy pip # 所有需要的公共依赖,必须和artiq要求的版本对齐 ''; }) ]; }; }; }
该方案的缺点是如果mach-nix安装的依赖版本和artiq要求的版本不一致,会出现覆盖导致运行时错误,适合依赖数量少、版本容易对齐的场景。
内容的提问来源于stack exchange,提问作者CharlieB
相关产品推荐
相关产品推荐

