Nix导入unstable时allowUnfree未生效,如何覆写nixpkgs配置?
解决Nixpkgs导入时覆写配置(allowUnfree)的问题
我之前也碰到过类似的情况,单独的nix文件里引用unstable分支时,allowUnfree总是不生效,还时不时出现config未定义的报错。其实核心问题在于:单独的包定义文件里没有全局的config变量(这个变量只在NixOS的主配置文件比如configuration.nix里才会被自动注入),所以得手动在导入nixpkgs的时候显式传递配置参数。
下面给你几个靠谱的解决方法,按推荐程度排序:
1. 导入nixpkgs时直接传入config参数
这是最直接也最不容易出错的方式,在import nixpkgs的时候,通过config参数把allowUnfree的设置传进去,这样导入的unstable实例会直接应用这个配置,完全不依赖全局变量。示例代码如下:
# package-upgrades.nix let # 导入unstable分支,同时指定允许非自由软件 unstable = import <nixpkgs-unstable> { config = { # 全局允许所有非自由软件 allowUnfree = true; # 如果只想给特定包开权限,可以用这个: # allowUnfreePredicate = pkg: pkg.name == "your-window-manager-package"; }; }; in { # 在这里使用unstable里的包,比如你的窗口管理器 myWindowManager = unstable.myWindowManager; # 其他需要升级的包也可以这么加 anotherPackage = unstable.anotherPackage; }
2. 对已导入的nixpkgs实例覆写配置
如果已经有一个导入好的unstable实例,不想重新导入的话,可以用extend方法来修改它的配置。不过这种方式要注意,有些包的构建逻辑可能已经依赖了初始的配置,所以不如第一种方法稳妥:
let # 先导入基础的unstable baseUnstable = import <nixpkgs-unstable> {}; # 覆写config参数 unstable = baseUnstable.extend (final: prev: { config = prev.config // { allowUnfree = true; }; }); in { # 使用覆写后的unstable包 myWindowManager = unstable.myWindowManager; }
3. Flake环境下的处理(如果用Flakes管理)
要是你用Flakes来组织配置的话,可以在flake.nix里直接给nixpkgs实例指定配置,再把这个实例传给你的package-upgrades.nix:
# flake.nix { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; }; outputs = { self, nixpkgs }: { packages.x86_64-linux = { myUpgradedPackages = let pkgs = import nixpkgs { system = "x86_64-linux"; config = { allowUnfree = true; }; }; in pkgs.callPackage ./package-upgrades.nix {}; }; }; }
为什么之前会出现「config未定义」的错误?
你之前碰到的这个错误,大概率是因为在代码里直接引用了config.allowUnfree——这个config是NixOS主配置里的全局变量,只有在configuration.nix这类系统配置文件里才会被自动加载。而在单独的package-upgrades.nix里,这个变量不存在,所以必须在导入nixpkgs时手动传递配置参数。
内容的提问来源于stack exchange,提问作者John Mercier
相关产品推荐
相关产品推荐

