As suggested in #131205.
Now it's possible to pretty-print a value with `lib.generators` like
this:
with lib.generators;
toPretty { }
(withRecursion { depthLimit = 10; } /* arbitrarily complex value */)
Also, this can be used for any other pretty-printer now if needed.
When having e.g. recursive attr-set, it cannot be printed which is
solved by Nix itself like this:
$ nix-instantiate --eval -E 'let a.b = 1; a.c = a; in builtins.trace a 1'
trace: { b = 1; c = <CYCLE>; }
1
However, `generators.toPretty` tries to evaluate something until it's
done which can result in a spurious `stack-overflow`-error:
$ nix-instantiate --eval -E 'with import <nixpkgs/lib>; generators.toPretty { } (mkOption { type = types.str; })'
error: stack overflow (possible infinite recursion)
Those attr-sets are in fact rather common, one example is shown above, a
`types.<type>`-declaration is such an example. By adding an optional
`depthLimit`-argument, `toPretty` will stop evaluating as soon as the
limit is reached:
$ nix-instantiate --eval -E 'with import ./Projects/nixpkgs-update-int/lib; generators.toPretty { depthLimit = 2; } (mkOption { type = types.str; })' |xargs -0 echo -e
"{
_type = \"option\";
type = {
_type = \"option-type\";
check = <function>;
deprecationMessage = null;
description = \"string\";
emptyValue = { };
functor = {
binOp = <unevaluated>;
name = <unevaluated>;
payload = <unevaluated>;
type = <unevaluated>;
wrapped = <unevaluated>;
};
getSubModules = null;
getSubOptions = <function>;
merge = <function>;
name = \"str\";
nestedTypes = { };
substSubModules = <function>;
typeMerge = <function>;
};
}"
Optionally, it's also possible to let `toPretty` throw an error if the
limit is exceeded.
m68k was recently added for Linux and none, but NetBSD also supports
m68k. Nothing will build yet, but I want to make sure we at least
encode the existence of NetBSD support for every applicable
architecture we support for other operating systems.
In 2d45a62899, the submodule type
description was amended with the freeformType description. This causes
all the modules passed to the submodule to be evaluated once on their
own, without any extra definitions from the config section. This means
that the specified modules need to be valid on their own, without any
undeclared options.
This commit adds a test that evaluates a submodules option description,
which would trigger the above problem for one of the tests, if it were
not fixed by this commit as well.
This is done because the next commit makes option evaluation a bit more
strict, which would also trigger this test failure, even though it's not
related to the change at all.
These are all the architectures supported by Nixpkgs on other
platforms, that are also supported by NetBSD. (So I haven't added
any architectures that are new to Nixpkgs here, even though NetBSD
supports some that we don't have.)
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.
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.
Previously the .enable option was used to encode the condition as well,
which lead to some oddness:
- In order to encode an assertion, one had to invert it
- To disable a check, one had to mkForce it
By introducing a separate .check option this is solved because:
- It can be used to encode assertions
- Disabling is done separately with .enable option, whose default can be
overridden without a mkForce
Previously this option was thought to be necessary to avoid infinite
recursion, but it actually isn't, since the check evaluation isn't fed
back into the module fixed-point.
- These symbols can be confusing for those not familiar with them
- There's no harm in making these more obvious
- Terminals may not print them correctly either
Also changes the function argument printing slightly to be more obvious