I recently wrote some Nix code where I wrongly set a value to an option
which wasn't an actual option, but an attr-set of options. The mistake I
made can be demonstrated with an expression like this:
{
foo = { lib, pkgs, config, ... }: with lib; {
options.foo.bar.baz = mkOption {
type = types.str;
};
config.foo.bar = 23;
};
}
While it wasn't too hard to find the cause of the mistake for me, it was
necessary to have some practice in reading stack traces from the module
system since the eval-error I got was not very helpful:
error: --- TypeError --------------------------------------------------------- nix-build
at: (323:25) in file: /nix/store/3nm31brdz95pj8gch5gms6xwqh0xx55c-source/lib/modules.nix
322| foldl' (acc: module:
323| acc // (mapAttrs (n: v:
| ^
324| (acc.${n} or []) ++ f module v
value is an integer while a set was expected
(use '--show-trace' to show detailed location information)
I figured that such an error can be fairly confusing for someone who's
new to NixOS, so I decided to catch this case in th `byName` function in
`lib/modules.nix` by checking if the value to map through is an actual
attr-set. If not, a different error will be thrown.
Usually we ensure using the mapAttrs call wrapping the license set that
every license has an associated shortName. A change related to legacy
aliases most likely introduced the removal of the shortName attribute
for all the legacy license names by splitting the set into two sets
connected by a record update operator -- leading to mapAttrs only
affecting the first set.
Since it used to be a valid assumption to have that every license had a
shortName attribute, we reintroduce this attribute for the legacy
aliases as well.
Forcing the module to be builtin breaks 5.10, which wants to compile it as a
module (probably due to dependencies). There doesn't seem to be a need to have
it builtin anymore, so we can just remove the override.
In 9c213398b3 kernelPreferBuiltin was
moved/renamed to linux-kernel.preferBuiltin. However, for
armv7l-hf-multiplatform the new option was written with an uppercase P,
which made the kernel build process ignore it.
This reverts commit d9a7d03da8.
Reason for this is that it actually doesn't migitate the issue on nix
stable for another reason: builtins.tryEval doesn't prevent the error
generated by builtins.functionArgs from halting evaluation:
> builtins.tryEval (builtins.functionArgs builtins.functionArgs)
error: 'functionArgs' requires a function, at (string):1:19
Thus it seems that there is no workaround to make
lib.generators.toPretty work with nix stable and primops since there is
no way to distinguish between primops and lambdas in nix.
An high level example case of this problem occuring can be found below:
nix-repl> lib.generators.toPretty {} (lib.concatStringsSep "\n")
error: 'functionArgs' requires a function, at /home/lukas/src/nix/nixpkgs/lib/trivial.nix:334:42
However this does not happen on other partially applied functions:
nix-repl> lib.generators.toPretty {} (lib.concatMapStringsSep "\n")
"<function>"
The issue, as it turns out is that while builtins are functions,
builtins.functionArgs throws if is passed a builtin or a partially
applied builtin:
nix-repl> lib.generators.toPretty {} builtins.toString
error: 'functionArgs' requires a function, at /home/lukas/src/nix/nixpkgs/lib/trivial.nix:334:42
nix-repl> lib.generators.toPretty {} (builtins.foldl' (a: b: a + b))
error: 'functionArgs' requires a function, at /home/lukas/src/nix/nixpkgs/lib/trivial.nix:334:42
I'm pretty sure this qualifies as a nix bug and should be filed
accordingly, but we can work around it in lib.generators.toPretty by
using tryEval and falling back to {} which functionArgs _should_ return
for builtins.
The nix behavior is inconsistent to say the least:
nix-repl> builtins.functionArgs builtins.functionArgs
error: 'functionArgs' requires a function, at (string):1:1
nix-repl> builtins.typeOf builtins.functionArgs
"lambda"
builtins.functionArgs (a: 1 + a)
{ }
nix-repl> builtins.typeOf (a: 1 + a)
"lambda"
PPC64 supports two ABIs: ELF v1 and v2.
ELFv1 is historically what GCC and most packages expect, but this is
changing because musl outright does not work with ELFv1. So any distro
which uses musl must use ELFv2. Many other platforms are moving to ELFv2
too, such as FreeBSD (as of v13) and Gentoo (as of late 2020).
Since we use musl extensively, let's default to ELFv2.
Nix gives us the power to specify this declaratively for the entire
system, so ELFv1 is not dropped entirely. It can be specified explicitly
in the target config, e.g. "powerpc64-unknown-linux-elfv1". Otherwise the
default is "powerpc64-unknown-linux-elfv2". For musl,
"powerpc64-unknown-linux-musl" must use elfv2 internally to function.
Now type checks the resulting function values and allows mkMerge and co.
Also indicates that the type check is done in the function body
Co-Authored-By: Robert Hensing <robert@roberthensing.nl>
Looks like these got left behind in the
kernelArch -> linuxArch migration.
Fixes:
* pkgsCross.powernv.linuxHeaders
* pkgsCross.riscv64.linuxHeaders
* pkgsCross.riscv32.linuxHeaders
and dependees
Immensely helpful when you want to see the changes a function makes to
its value as it passes through.
Example:
```
$ nix-instantiate --strict --eval -E '(with import ./lib; traceFnSeqN 2 "id" (x: x) { a.b.c = 3; })'
trace: {
fn = "id";
from = {
a = {
b = {…};
};
};
to = {
a = {
b = {…};
};
};
}
{ a = { b = { c = 3; }; }; }
```
This reverts commit 4ff1ab5a56.
We need this to type options like:
services.xserver.windowManager.xmonad.extraPackages that specify functions that
take an attribute set containing packages / plugins and return a list containing
a selection of the values in this set.
The reason we need a dedicated type for this is to have the correct merge
behaviour. Without the functionTo type merging multiple function option
definitions results in an evaluation error. The functionTo type merges
definitions by returning a new function that applies the functions of all the
definitions to the given input and merges the result.
(cherry picked from commit 7ed41ff5e7)
The `platform` field is pointless nesting: it's just stuff that happens
to be defined together, and that should be an implementation detail.
This instead makes `linux-kernel` and `gcc` top level fields in platform
configs. They join `rustc` there [all are optional], which was put there
and not in `platform` in anticipation of a change like this.
`linux-kernel.arch` in particular also becomes `linuxArch`, to match the
other `*Arch`es.
The next step after is this to combine the *specific* machines from
`lib.systems.platforms` with `lib.systems.examples`, keeping just the
"multiplatform" ones for defaulting.
For renames like
mkAliasOptionModule [ "services" "compton" ] [ "services" "picom" ]
where the target is an option set (like services.picom) instead of a single
option (like services.picom.enable), previously the renamed option type
was unset, leading to it being `types.unspecified`.
This changes it to be `types.submodule {}` instead, which makes more
sense.
Since 40e7be1 all ARM platforms that didn't have a parsed cpu version
(e.g. arm-none-eabi) would be handled as armv7l-hf-multiplatform which
did break building arm-trusted-platform packages for some targets (e.g.
rk3399).
Using pcBase as fallback, instead of armv7l-hf-multiplatform,
corresponds with the behaviour we had before 40e7be1.
We recently switched to more explicit GPL license names in line
with the SPDX change and GNU Foundation recommendations:
https://www.gnu.org/licenses/identify-licenses-clearly.html
This followed up older change to use the recommended SPDX ID
18a5e8c36b
but using the `-only` variant for these deprecated licenses too
makes it harder to check for them automatically.
Let’s switch to the appropriate SPDX ID again.