假设我有一个非常简单的NixOS 配置文件:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# SOME STUFF
environment.systemPackages = with pkgs; [ emacs gitFull ];
# SOME STUFF
}
Run Code Online (Sandbox Code Playgroud)
我知道 NixOS 实现了一个模块系统,一个模块就是一个.nix
文件。每个.nix
文件都应该包含任何有效的Nix 表达式(例如一个函数或一个集合)。这意味着 NixOS 配置文件/etc/nixos/configuration.nix
本身就是一个模块,包含一个 Nix 表达式。
我也知道要使另一个模块中的 Nix 表达式对我正在使用的模块可见,我可以使用内置import
函数。
我想将系统包的声明(包含emacs
和的列表gitFull
)拆分为 file packages.nix
。如何将 NixOS 配置文件拆分为单独的模块?
Mir*_*lov 24
一个尼克斯的表达就像任何编程语言的表达:任何计算结果为数值或功能。这种情况下的值也可以是列表或集合。作为 Nix 模块(带有扩展名的文件.nix
)可以包含任何 Nix 表达式,您希望 NixOS 配置文件 ( /etc/nixos/configuration.nix
) 包含单个 Nix 表达式作为其文件内容。
NixOS 配置文件包含以下形式的 Nix 表达式:
{config, pkgs, ...}: { /* various configuration options */ }
Run Code Online (Sandbox Code Playgroud)
如果你仔细观察,你会发现它是一个函数,因为函数遵循形式pattern: form
。您还可以看到它是一个接受集合并返回集合的函数。例如,如果您有一个 function f = {x, y}: {a = x + y;}
,那么您可以将其称为 asf {x=1; y=2;}
并返回一个 set {a=3;}
。
因此,这意味着当您调用 时nixos-rebuild switch
,某些东西会调用 NixOS 配置文件中的函数,并使用必须包含属性config
和pkgs
.
下面的例子./hardware-configuration.nix
,简单的方法来提取的软件包列表到一个单独的模块packages.nix
就是翻录environment.systemPackages
选项,并把./packages.nix
进入imports
选项。你/etc/nixos/configuration.nix
会看起来像:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
Run Code Online (Sandbox Code Playgroud)
你/etc/nixos/packages.nix
会看起来像:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?当您运行 时nixos-rebuild switch
,评估 Nix 表达式并决定安装包等的过程会configuration.nix
使用一组属性调用,其中一些属性是config
和pkgs
。
它发现属性imports
返回set里面,所以它的计算结果中的模块,每一个尼克斯表达imports
使用相同的参数(包含config
,pkgs
等)。
你必须有pkgs
一个函数的参数(或者,从技术上讲,一个集合的属性,它本身就是一个参数) in packages.nix
,因为,从 Nix 语言的角度来看,这个过程可能会也可能不会调用带有集合的函数包含pkgs
. 如果不是,你会在运行时引用什么属性with pkgs
?
您还必须有省略号,因为可能会使用其他属性调用该函数,而不仅仅是pkgs
.
为什么没有pkgs
在configuration.nix
?您可以拥有它,但如果您不在文件中的任何地方引用它,则可以放心地省略它,因为无论如何省略号都会包含它们。
另一种方法是创建一个函数,该函数返回一个具有某些属性的集合,并将该属性的值放入environment.systemPackages
. 这是你的configuration.nix
:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# SOME STUFF
environment.systemPackages = import ./packages.nix pkgs;
# SOME STUFF
}
Run Code Online (Sandbox Code Playgroud)
你的packages.nix
:
pkgs: with pkgs; [ emacs gitFull ]
Run Code Online (Sandbox Code Playgroud)
import ./packages.nix pkgs
意思是:加载并返回 Nix 表达式./packages.nix
,因为它是一个函数,使用参数调用它pkgs
。with pkgs; [ emacs gitFull ]
是一个with-expression,它将分号之前的表达式的范围带到分号之后的表达式。没有它,它将是[ pkgs.emacs pkgs.gitFull ]
。
归档时间: |
|
查看次数: |
5073 次 |
最近记录: |