-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
package overrides using a mini module system #312432
base: master
Are you sure you want to change the base?
Conversation
My thoughts on this draft: Unfortunately we can't measure the performance impact by adding only a handful of examples. With the Nixpkgs architecture team, we've looked into applying the module system more broadly. See e.g. Reducing the scope of module system usage may alleviate the performance issue somewhat, but then the question is whether this is the most effective allocation of our evaluation performance "budget". (I don't have an answer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this! Not because I'm hopeful about the performance improvement (in fact I'm skeptic about this detail), but mostly because finally options have a description written with Nix and not in a comment.
Obviouslt my question is: how hard will be to teach this to newcomers? |
Teach what to newcomers? The module system they likely already use in NixOS? |
Yes, given that Nixpkgs is not tied to NixOS. |
What part do you expect to be hard to teach to newcomers? From the perspective of a user, they provide an attrset of configuration either way. I don't see how usage of this API would be any harder to understand than the status quo; using a module system requires basically no knowledge of its internal mechanisms. I'd argue it'd be slightly simpler to use actually because error messages would be a lot easier to understand: "anonymous function at ... called with unexpected argument withFoo" vs. "the option foo does not exist". And that's ignoring the errors you could catch via typecheck instead of incredibly confusing "cannot coerce ... into a string". |
Any part not well documented, to begin with. https://nixos.org/manual/nixpkgs/stable/#module-system
(bold mine) |
I do not see how the developer documentation for setting up a module system would be relevant to users merely using a module system that someone else already set up. As per my previous comment, no newcomer needs to know about the module system's internal mechanisms in order to configure something with it. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/a-sad-state-of-nixpkgs/49397/5 |
I just noticed that there has been prominent precedent for this in Nixpkgs for many years now: The structured Linux kernel config drv. It uses much the same pattern as what I "came up" with. (I didn't actively think of the kernel config but it may have subconsciously influenced me.) |
Now produces the same buildInputs (modulo order) as the regular ffmpeg
Slightly less nice but necessary because we pass packages individually
I don't think we have that many packages that would want to use this module system, hence I don't consider this price as too high for gradual insertion of this feature into Nixpkgs. I'd like to see this getting moved forward by rebasing etc, and see ofborg's checks will be green. I'd also like to practice afterwards in converting Gnuradio's and I'd also like to discuss how the docs would look like. |
I'm confident ofBorgs checks will pass because this evals to the exact same result (modulo order). |
You can simply pass it to make, no need for a custom checkPhase
I've done a few more cleanups and refactors and I think I'm at a point where I'm quite happy with how the ffmpeg derivation turned out and can't immediately think of anything I'd change about the design anymore. |
"--target_os=${if stdenv.hostPlatform.isMinGW then "mingw64" else stdenv.hostPlatform.parsed.kernel.name}" | ||
"--arch=${stdenv.hostPlatform.parsed.cpu.name}" | ||
"--pkg-config=${buildPackages.pkg-config.targetPrefix}pkg-config" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've decided to keep these flags be managed manually; without implying them from the modules eval. Rationale being that it's just a few and they're not really something you'd usually (if ever) want to touch.
Forgot to actually delete it a few commits ago
I'm pretty much on the same page w.r.t. eval time increase. For now, this only really makes sense to do in complex packages such as ffmpeg or Linux. A suspected eval time increase by ~1 standard deviation (10^-2 s) isn't a great cost to pay considering a typical NixOS eval takes 2-3 orders of magnitude longer. While I'd like better documentation, the status quo is that nothing about package customisation is documented outside of code and its comments which is retained. I'd rather wait until we have a proper place and system coordinated for that at which point it should be trivial to plug ffmpeg's options into that. What I'd like to discuss more is how to handle the override situation as it's all but intuitive or easy and I can't think of an easy solution. The best I can currently come up with is a dedicated override function (i.e. overrideFeatures). |
Which would just be a thin wrapper around
It doesn't feel like a big deal to me - we have a place already to document how to use Nix expressions of packages, it's just not automatically generated. I agree we don't have to settle now on how exactly to build the workflow of adding these docs automatically, but I'd like to see that it is at least possible to generate some documentation files automatically from these expressions. |
It'd work as described in the OP. Though implementing it could be tricky because an override functions' scope is not local to the package.
Where? That's news to me.
This already works for NixOS, I don't see why it wouldn't work here aswell. In fact, you can already introspect the documentation using a repl/nix-instantiate:
|
I tried it and it's trivial: What I noticed is that it puts a literal |
Hmm OK I see. Now I read in the OP that it is only an issue with multiple overrides? Why would someone need to do that? |
It's only an issue with composing overrides indeed but you never know what people might need to do with your derivation. |
multiple overrides are definitely a thing in nixos consider a module which provides a i don't recall the concrete example to link at the moment but i if you look you will find it |
Steam does this for instance: nixpkgs/nixos/modules/programs/steam.nix Lines 45 to 65 in 8c9630d
As you can see, it also needs to take great care of overriding in a composable manner but that's only necessary when composing values of arguments; composing top-level arguments themselves without "deeper" values is trivial. |
Darwin eval works now
Description of changes
Putting a package's configuration options into function arguments in order to expose them via
override
is a well established pattern but has major issues:?
and no ability to use let bindings)But we have a well-established solution to all those problems: The module system.
This is a little thought that came to my mind while thinking about RFC 169:
Why couldn't we just use the module system for configuring packages?
The extent to which this is done here is merely the configuration options that were explicitly exposed by the package before which is similar to how modules are used NixOS; explicit options provided by the package maintainer to customise some specific aspect of the package.
The only limitation I currently see is that it is a bit awkward to compose multiple overrides:
This could however be remedied using a dedicated
overrideFeatures
function.As for performance:
Edit: Out of date. See below.
Previous:
With modules:
There might be a slight difference here but none that I could measure using runtime.
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.