Home Explore Blog CI



nixpkgs

2nd chunk of `nixos/doc/manual/configuration/modularity.section.md`
ada1c22a5be619ef3b575ac20f57a5fe06355e0afbe749770000000100000beb
Note that both `configuration.nix` and `kde.nix` define the option
[](#opt-environment.systemPackages). When multiple modules define an
option, NixOS will try to *merge* the definitions. In the case of
[](#opt-environment.systemPackages) the lists of packages will be
concatenated. The value in `configuration.nix` is
merged last, so for list-type options, it will appear at the end of the
merged list. If you want it to appear first, you can use `mkBefore`:

```nix
{
  boot.kernelModules = mkBefore [ "kvm-intel" ];
}
```

This causes the `kvm-intel` kernel module to be loaded before any other
kernel modules.

For other types of options, a merge may not be possible. For instance,
if two modules define [](#opt-services.httpd.adminAddr),
`nixos-rebuild` will give an error:

```plain
The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'.
```

When that happens, it's possible to force one definition take precedence
over the others:

```nix
{
  services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org";
}
```

When using multiple modules, you may need to access configuration values
defined in other modules. This is what the `config` function argument is
for: it contains the complete, merged system configuration. That is,
`config` is the result of combining the configurations returned by every
module. (If you're wondering how it's possible that the (indirect) *result*
of a function is passed as an *input* to that same function: that's
because Nix is a "lazy" language --- it only computes values when
they are needed. This works as long as no individual configuration
value depends on itself.)

For example, here is a module that adds some packages to
[](#opt-environment.systemPackages) only if
[](#opt-services.xserver.enable) is set to `true` somewhere else:

```nix
{ config, pkgs, ... }:

{ environment.systemPackages =
    if config.services.xserver.enable then
      [ pkgs.firefox
        pkgs.thunderbird
      ]
    else
      [ ];
}
```

With multiple modules, it may not be obvious what the final value of a
configuration option is. The command `nixos-option` allows you to find
out:

```ShellSession
$ nixos-option services.xserver.enable
true

$ nixos-option boot.kernelModules
[ "tun" "ipv6" "loop" ... ]
```

Interactive exploration of the configuration is possible using `nix
  repl`, a read-eval-print loop for Nix expressions. A typical use:

```ShellSession
$ nix repl '<nixpkgs/nixos>'

nix-repl> config.networking.hostName
"mandark"

nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts
[ "example.org" "example.gov" ]
```

While abstracting your configuration, you may find it useful to generate
modules using code, instead of writing files. The example below would
have the same effect as importing a file which sets those options.

```nix
{ config, pkgs, ... }:

let netConfig = hostName: {
  networking.hostName = hostName;
  networking.useDHCP = false;
};

in

{ imports = [ (netConfig "nixos.localdomain") ]; }
```

Title: Merging and Accessing Configuration Values in NixOS Modules
Summary
When multiple modules define the same option, NixOS merges them where possible, such as concatenating lists for `environment.systemPackages`. `mkBefore` can prioritize list elements. Conflicting definitions, like for `services.httpd.adminAddr`, cause errors unless forced with `pkgs.lib.mkForce`. The `config` argument allows modules to access the complete, merged system configuration. Conditional configurations, like adding packages based on `services.xserver.enable`, are possible. `nixos-option` and `nix repl` help inspect final option values. Modules can also be generated programmatically using functions.