I have recently seen PRs, where the commonly-used pattern:
Derivation:
{ jdk, ...}:
all-packages.nix:
somepackage = {
jdk = jdk8;
};
is replaced by, or not used in favor of, another commonly-used pattern:
{ jdk8, ...}:
let
jdk = jdk8;
in mkDerivation {
# ...
buildInputs = [ jdk8 ];
# ...
}
I wonder if there is any consensus on which pattern is preferred. Personally, I dislike the latter pattern, because it makes overriding packages less intuitive. E.g.
somepackage.override { jdk = jdk11; };
becomes:
somepackage.override { jdk8 = jdk11; };
Moreover, if the jdk8 attribute is later changed to jdk11, overrides that a user may have become invalid, because the jdk8 attribute is not available anymore.
I can see that for packages that are very strongly tied to particular versions of a runtime or library, it makes sense to hardcode the dependency. However, newer versions of e.g. Java runtimes or CUDA toolkits are generally backwards compatible.
That’s mostly what happened in #89731. I tried to override as much as possible in all-packages.nix, and only change the derivation file when I got a build error with the new jdk. In some other cases it was infeasible to override from all-package.nix, e.g. in chromium, also in that case I changed the derivation file.
Sorry, I probably shouldn’t have cited this PR (which is very useful), so I have removed the link.
It’s something I just noticed in various PRs that both patterns occur and reviewers sometimes ask people to modify derivations in one direction or the other.
I found this thread while researching examples for a good way to do the jdk version in the clojure derivation more configurable. In this particular case, I want to default to jdk11 (since clojure officially only supports java LTS releases).
I see pros and cons on both proposed patterns, I’d like to know what do you think about a 3rd pattern:
IMO that makes clear that there is a preferred jdk version, but overriding packages is still intuitive and changes to the version will not break user overrides. Also, it makes unnecessary to update all-packages.nix
This is also my experience, and because of this, my personal preference is to:
generally: use jdk in default.nix (pointing to the latest JDK)
when a package does not work with the latest JDK: use jdk8 (or whatever) in the package’s default.nix.
This helps us detect problems as soon as possible, and reduces spreading information between all-packages.nix and default.nix.
You’re right that, for packages that need a particular JDK version, overriding the JDK becomes a bit awkward - but that should be the exception rather than the norm anyway.
(I’m not strongly opposed to using jdk in default.nix and overriding it as needed in all-packages.nix, though. By the way, for python we should explicitly use python3 as discussed in Should `python` point to python3? - #7 by jonringer)
There is no consensus and it’s an easy thing to bikeshed about.
I have an opinion (as stated in the first post). But I care more about having a rule than it being my preferred rule, since now PR submitters will get comments (or not) based on which reviewer looks at a PR. This also happens in somewhat similar cases (e.g. should the darwin frameworks that a derivation uses be enumerated in all-packages.nix or can a derivation just use e.g. darwin.Security).
Or perhaps we don’t need a rule, but we should not hold up PRs based on such preferences.
Totally agree, but it seems difficult to find a consensus.
I want to create a PR for the clojure derivation, but now I’m even more unsure about the pattern to use. BTW, do you see problems with the 3rd pattern I proposed in my previous post?
Other then that, the very uncommon (for AFAIK) pattern with pkgs imported to the derivation, might introduce an unjustified increase in evaluation time - I can’t find a metric for that, but in general using pkgs inside a derivation feels bad to me.