1# Option Definitions {#sec-option-definitions} 2 3Option definitions are generally straight-forward bindings of values to 4option names, like 5 6```nix 7config = { 8 services.httpd.enable = true; 9}; 10``` 11 12However, sometimes you need to wrap an option definition or set of 13option definitions in a *property* to achieve certain effects: 14 15## Delaying Conditionals {#sec-option-definitions-delaying-conditionals} 16 17If a set of option definitions is conditional on the value of another 18option, you may need to use `mkIf`. Consider, for instance: 19 20```nix 21config = if config.services.httpd.enable then { 22 environment.systemPackages = [ ... ]; 23 ... 24} else {}; 25``` 26 27This definition will cause Nix to fail with an "infinite recursion" 28error. Why? Because the value of `config.services.httpd.enable` depends 29on the value being constructed here. After all, you could also write the 30clearly circular and contradictory: 31 32```nix 33config = if config.services.httpd.enable then { 34 services.httpd.enable = false; 35} else { 36 services.httpd.enable = true; 37}; 38``` 39 40The solution is to write: 41 42```nix 43config = mkIf config.services.httpd.enable { 44 environment.systemPackages = [ ... ]; 45 ... 46}; 47``` 48 49The special function `mkIf` causes the evaluation of the conditional to 50be "pushed down" into the individual definitions, as if you had written: 51 52```nix 53config = { 54 environment.systemPackages = if config.services.httpd.enable then [ ... ] else []; 55 ... 56}; 57``` 58 59## Setting Priorities {#sec-option-definitions-setting-priorities} 60 61A module can override the definitions of an option in other modules by 62setting an *override priority*. All option definitions that do not have the lowest 63priority value are discarded. By default, option definitions have 64priority 100 and option defaults have priority 1500. 65You can specify an explicit priority by using `mkOverride`, e.g. 66 67```nix 68services.openssh.enable = mkOverride 10 false; 69``` 70 71This definition causes all other definitions with priorities above 10 to 72be discarded. The function `mkForce` is equal to `mkOverride 50`, and 73`mkDefault` is equal to `mkOverride 1000`. 74 75## Ordering Definitions {#sec-option-definitions-ordering} 76 77It is also possible to influence the order in which the definitions for an option are 78merged by setting an *order priority* with `mkOrder`. The default order priority is 1000. 79The functions `mkBefore` and `mkAfter` are equal to `mkOrder 500` and `mkOrder 1500`, respectively. 80As an example, 81 82```nix 83hardware.firmware = mkBefore [ myFirmware ]; 84``` 85 86This definition ensures that `myFirmware` comes before other unordered 87definitions in the final list value of `hardware.firmware`. 88 89Note that this is different from [override priorities](#sec-option-definitions-setting-priorities): 90setting an order does not affect whether the definition is included or not. 91 92## Merging Configurations {#sec-option-definitions-merging} 93 94In conjunction with `mkIf`, it is sometimes useful for a module to 95return multiple sets of option definitions, to be merged together as if 96they were declared in separate modules. This can be done using 97`mkMerge`: 98 99```nix 100config = mkMerge 101 [ # Unconditional stuff. 102 { environment.systemPackages = [ ... ]; 103 } 104 # Conditional stuff. 105 (mkIf config.services.bla.enable { 106 environment.systemPackages = [ ... ]; 107 }) 108 ]; 109```