Not really. Looking at genAttrs
, it says that it's genAttrs :: [ String ] -> (String -> Any) -> AttrSet
, and the example code is
genAttrs [ "foo" "bar" ] (name: "x_" + name)
=> { foo = "x_foo"; bar = "x_bar"; }
So I'd expect a list of strings and the mapping function. However, from my first naive glance at the code you posted, there's no list of strings there, and rather directly a function definition
That's my bad. I didn't actually look at how the function works, so I got the arguments flipped. This is just a rough outline of how I'd imagine it to work; pseudo-code. 100% untested. Only there for the sake of argument.
packageNamesToModify
is the list of strings you're looking for here. As I said though, I can't know which packages are supposed to be changed. That's a piece of info you'd need to research and define yourself. This is just how you'd apply that knowledge through a mechanism.
that makes use of overrideAttrs, for which for me the documentation is unclear if it can only set attributes, create attributes or what else
A function cannot "set" or "create" attributes. For better of for worse, there's no real meta-programming in Nix.
A function can only ever return a value. That value may be any of the primitive types such as booleans, strings, numbers, lists, attrsets etc. or even another function but it's always a value.
In the case of overrideAttrs { ... }
, the return value is a derivation. In the case of genAttrs
, it's an attrset.
buildInputs
at first naive glance isn't an attribute of the packages, but rather of stdenv
(sorry if all of this is wrong)
That is correct. However note how I said that overrideAttrs
is about overriding arguments to mkDerivation
? The canonical path to mkDerivation
is stdenv.mkDerivation
;)
mkDerivation
is the way you set arguments for the stdenv. .overrideAttrs
is how you "modify" the arguments to the stdenv of an existing package.
all of which isn't exactly intuitive if you've only worked with imperative languages.
I can absolutely see that. You'll get used to it though. When I was new to Nix, it took me quite a while to realise how you'd even do something like creating loops (spoiler: you don't).
I'd highly recommend familiarising yourself with basic functional programming concepts such as immutability, everything being a value (including functions, see lambdas), recursion, basic functional list comprehension (head/tail, map, filter, reduce) and perhaps even currying.
Nix is a great learning ground for the basics of functional programming as it's a pure expression language which is quite a bit more limited than an actual functional programming language.
I tripped over some stuff back then when I found out that which
is not part of the sandbox.
That's what buildInputs
are for. Add which
to buildInputs
and it's available inside the sandbox. The stdenv takes care of putting its binaries into $PATH
and making its libraries discoverable.
In the case of which
, you'd probably need it in order to execute its binary during the build process though, so nativeBuildInputs
is more appropriate but that only truly matters for cross-compilation.