Skip to content

Typed nixpkgs.config with Gentoo-like use-flags#56227

Closed
oxij wants to merge 12 commits intoNixOS:masterfrom
oxij:tree/ultimate-use-flags
Closed

Typed nixpkgs.config with Gentoo-like use-flags#56227
oxij wants to merge 12 commits intoNixOS:masterfrom
oxij:tree/ultimate-use-flags

Conversation

@oxij
Copy link
Copy Markdown
Member

@oxij oxij commented Feb 23, 2019

What?

This patchset does two things:

The first part is inspired by and is similar to #43672 by @matthewbauer (but it is simpler than #43672 module-mechanics-wise and less comprehensive option-wise, that latter part and removal of or false from config\..* or false and similar is left for future work if this gets merged).

The second part is inspired by #56109 by me and #56110 (comment) by @danbst, and is similar in function to #39580 by @matthewbauer (but it doesn't use overlays, which makes this very cheap (this patchset is unnoticeable in metrics, the impact of ~0.02% on allocations and something unmeasurable on eval time), and without pkgs scope pollution with any new attributes).

Why?

See commit messages below, #43672, #12877, #39580.

git log

  • pkgs/top-level/stage.nix: don't override overlays and config in nixpkgsFun

    nixpkgsFun already sets them. The next patch will also make
    nixpkgsFun use the original config while stage.nix will get the
    processed one. Mixing them up can cause unexpected errors.

  • pkgs/top-level: check types of nixpkgs.config

    This patch simply introduces a plain simple NixOS module and passes
    nixpkgs.config through it via evalModules (with some temporary hackery to
    passthru undefined options).

  • lib: add extra property to mkOption

  • top-level: introduce Gentoo-like global USE flags

    This uses the above nixpkgs.config infra to make nixpkgs.config.use option
    set that influences the default scope of callPackage and etc, thus
    implementing Gentoo-like use flags.

    Note that the whole point of use-flags is that they cover use cases not covered
    by overlays and overrides. For instance, it is very hard to maintain a working
    overlay of headless packages (as minimal.nix profile of NixOS dutifully
    demonstrates, see Top-level nixpkgs-headless package set #29135 for more discussion), but it is almost trivial to make
    such a thing using use-flags.

    Moreover, influencing the default scope of callPackage and etc allows one to
    override all packages in pkgs all at once while keeping pkgs scope as-is.
    For instance, by setting x11Support = false in callPackage scope one
    will (in the ideal world, Nixpkgs' reality is much more cruel, see the actual
    patch) disable X11 support in all the packages while keeping, e.g. xlib
    available. The combination of these two properties
    (influencing all the packages while keeping the pkgs scope) is impossible to
    achieve with overlays without manually overriding almost every single package in
    scope.

nix-instantiate environment

  • Host OS: Linux 4.9, SLNOS 19.03
  • Nix: nix-env (Nix) 2.1.3
  • Multi-user: yes
  • Sandbox: yes
  • NIXPKGS_CONFIG:
{
  checkMeta = true;
  doCheckByDefault = true;
}

nix-env -qaP diffs

  • On x86_64-linux: noop
  • On aarch64-linux: noop
  • On x86_64-darwin:
    • New (9):
      • darkice
      • libretro.mame
      • mathematica
      • openmsx
      • pmidi
      • rtaudio
      • rtmidi
      • shairport-sync
      • traverso

Notes

Note that the above diff shows that this adds some packages on Darwin. "WTF?" you may rightfully ask after reading the changes.

What happens there is the above infra has config.use.alsa disabled on Darwin by default, which "overrides" all packages with corresponding scope changes on Darwin, thus removing alsaLib dependencies from the above packages, thus allowing above packages to be evaluated on Darwin. If stuff like this isn't cool, then I don't know what is.

I also wanted to disable PulseAudio on Darwin, because AFAIK nobody runs it on Darwin anyway, but that changes a lot of packages, so I decided against it for now.

What's next?

  • If this gets merged:

    • Most of Create config builder to handle default config values #43672 should be ported on top of this to simplify config handling in the rest of nixpkgs.

    • Old config options, including those defined by packages, need to be added, a lot of them can then be depricated using normal NixOS module mechanisms like mkRenamedOptionModule and etc.

    • Ideally, package options need to be cleaned up.

  • If not:

    • Unlike [Demo, RFC] Gentoo-like use-flags #56110 this is not a "demo". Clearly, this patchset can be managed outside of Nixpkgs tree without any cooperation from Nixpkgs. I.e. unless/until there's a clearly superior implementation of this I will maintain this as the first public branch of SLNOS.

@grahamc
Copy link
Copy Markdown
Member

grahamc commented Feb 23, 2019

On #56110 you got a 👎 from @edolstra and I suggested we should probably make an RFC out of it. In #56158 you said:

@7c6f434c I think RFCs make sense for something non-trivial, massive, or controversial. This and #56227 are neither.

It may be conceptually not much, or code-wise not much, but it is a big change -- one which has been discussed in the past. I still think an RFC might be in order.

@oxij oxij force-pushed the tree/ultimate-use-flags branch from a3de4f9 to c805ccd Compare February 23, 2019 04:25
@oxij
Copy link
Copy Markdown
Member Author

oxij commented Feb 23, 2019

@grahamc I see why @edolstra would 👎 #56110, it needs a huge change to the rest of nixpkgs to work. This thing is small and pretty trivial.

If there is a consensus that this needs an RFC then, if somebody else wants to do it, I'm not against it, if you want me to do it, then it won't happen soon, as my free time ends tomorrow and I won't have a long span I can commit to nixpkgs for a while.

@grahamc
Copy link
Copy Markdown
Member

grahamc commented Feb 23, 2019

Let's see what other people think :)

@oxij oxij force-pushed the tree/ultimate-use-flags branch from c805ccd to ccea0f8 Compare February 23, 2019 05:56
@dtzWill
Copy link
Copy Markdown
Member

dtzWill commented Feb 23, 2019

Still catching up on things but this looks great!

Tiny minor nit: if v ? extra then v.extra else XYZ is simpler as v.extra or XYZ. Possibly slightly friendlier to eval but mostly I think it's a lot easier to read (although it's used sparingly enough it's easy to miss that or is an operator and isn't logical or bitwise but something else :)).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you save half of the lines here by calling mkMassRebuild? (and half of the wondering whether there is a subtle difference)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not used anywhere, right? Maybe add a comment explaining the argument order swap?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, sorry, only whenEnabled is not used — and I see the currying benefits of whenDisable — which might still be worth a comment.

@7c6f434c
Copy link
Copy Markdown
Member

I think this is cheap (unlike overlays…), relies on the code already there and makes the use of the flags more consistent.

Maybe it should be explicitly mentioned in some comment that non-default values of USE flags are not tested, not provided by Hydra and might not be well maintained; especially if one has two non-default flags set…

@oxij oxij force-pushed the tree/ultimate-use-flags branch from ccea0f8 to 315f483 Compare February 23, 2019 18:31
@oxij oxij requested a review from infinisil as a code owner February 23, 2019 18:31
@oxij
Copy link
Copy Markdown
Member Author

oxij commented Feb 23, 2019 via email

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# experince here.)
# experience here.)

@oxij oxij force-pushed the tree/ultimate-use-flags branch from 315f483 to 8adad43 Compare February 23, 2019 18:43
@GrahamcOfBorg GrahamcOfBorg added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Feb 23, 2019
@matthewbauer
Copy link
Copy Markdown
Member

Some of this stuff looks good, but I disagree with the high level goal of adding use-flags. While I previously thought it was a good goal for Nixpkgs to have, I now think it would make the end user experience worse. The two main reasons are:

  1. Any non-trivial USE flags are going to cause mass rebuilds. Unlike Gentoo, very few users expect to have to rebuild everything from source. It also leads to fragmentation, where we now need to know what USE flags you have set when you report that something is broken. We have a hard enough time getting things to work correctly in vanilla Nixpkgs without having to worry about every permutation of Nixpkgs a user might have (this of course applies to overlays too, but i think there is less of an expectation that an overlay will work). For this same reason, I think we should start discouraging config flags like config.pulseaudio or config.cudaSupport as they are almost guaranteed to be broken without having a whole new jobset on Hydra.

  2. You can accomplish the exact same thing as USE flags with your own overlay. As long as you know which packages you are using, you just have to do an override for each package with the flag. This is both more specific and more flexible than Gentoo's USE flags. There are definitely some improvements possible for this like standardizing the naming of the arguments (as seen in many extra args here). I think we should encourage overlays instead of trying to port the USE system over to Nixpkgs. If someone wants to start maintaining these, that would be very useful for the community, but they should be separate from Nixpkgs.

These are mainly pragmatic reasons and I definitely set the allure of USE flags. I just think the same thing could be accomplished with overlays, with much more specificity, and less mass rebuilds.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit weird to have one feature attribute getting put into Whether to enable ${args.feature} support for nixpkgs packages., accepts values like "X11", and another feature attribute getting put into Whether to ${args.feature} while evaluating nixpkgs., accepting values like "run foobar". It might make sense to give them a different name, the latter one could be renamed to action.

In addition I fear it might end up like mkEnableOption "foo" where people don't know that Whether to enable ${arg}. gets put around their argument. But I guess writing such config options isn't as common as NixOS modules.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should change nixpkgs to use a single variant throughout, but this could be done in a future PR.

lib/options.nix Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unnecessarily hacky way to get the functionality you're implementing with it. If you need additional module settings when options have a certain value, use a proper module for that instead of abusing mkOption's arguments.

Do to this you'll need to do a data transformation for config.nix, changing all the foo = mkUse { ... } into a list of modules that each define the option and do the extra things.

Or just write it as a normal module, with additional config being applied in the config section.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to introduce preliminary aliases. We can always add them later if they're really wanted.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and I like that!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as modules = [ ./config.nix ...

@oxij
Copy link
Copy Markdown
Member Author

oxij commented Feb 24, 2019 via email

@oxij
Copy link
Copy Markdown
Member Author

oxij commented Feb 24, 2019 via email

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 1, 2020
@ryantm ryantm added 2.status: merge conflict This PR has merge conflicts with the target branch and removed 2.status: merge conflict This PR has merge conflicts with the target branch labels Oct 3, 2020
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Oct 3, 2020
@ryantm ryantm added the 2.status: merge conflict This PR has merge conflicts with the target branch label Oct 3, 2020
@nixos-discourse
Copy link
Copy Markdown

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/flag-packages-out-of-date/12612/13

@WillPower3309
Copy link
Copy Markdown
Contributor

What is currently holding this PR back?

@stale
Copy link
Copy Markdown

stale bot commented Nov 9, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Nov 9, 2021
@ghost

This comment was marked as off-topic.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Dec 20, 2021
@FRidh FRidh mentioned this pull request Apr 4, 2022
13 tasks
@roberth
Copy link
Copy Markdown
Member

roberth commented Apr 4, 2022

What is currently holding this PR back?

It has too many changes, one of which is not viable: use flags. See start of discussion.

Some changes are viable, but are better applied in separate PRs.

Furthermore, the author seems to have stopped contributing to Nixpkgs.

As such, it seems better to close this PR than to leave it open. It can be reopened if the author reduces the scope of the changes, although a split into smaller PRs is to be preferred.

@roberth roberth closed this Apr 4, 2022
@WillPower3309
Copy link
Copy Markdown
Contributor

What is currently holding this PR back?

It has too many changes, one of which is not viable: use flags. See start of discussion.

Some changes are viable, but are better applied in separate PRs.

Furthermore, the author seems to have stopped contributing to Nixpkgs.

As such, it seems better to close this PR than to leave it open. It can be reopened if the author reduces the scope of the changes, although a split into smaller PRs is to be preferred.

Definitely understandable, although for the case of use flags, aren't they essentially just global overrides? Seems like an easier way to deal with options than package by package if you want to apply something globally. Eh, this is probably a discussion for a more focused PR.

@roberth
Copy link
Copy Markdown
Member

roberth commented Apr 5, 2022

Honestly, part of the reason is trying to engineer things such that we don't override as much, making binary caches more effective and reducing support load. Support which is handled by passionate people in their spare time.

So yes, your argumentation is correct, but does not override the sustainability of the project.

@nixos-discourse
Copy link
Copy Markdown

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/where-are-optional-deps-in-nixpkgs-standardised-as-a-prominent-reference-for-pkgs-authors/30397/1

default = builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1";
defaultText = ''builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1"'';
feature = "permit evaluation of broken packages";
};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some of these in pkgs/top-level/config.nix now, but they're not nearly as complete, so they're still worth adding.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(except for the new ones that don't exist yet)

@oxij
Copy link
Copy Markdown
Member Author

oxij commented Jul 17, 2023 via email

@WillPower3309
Copy link
Copy Markdown
Contributor

Eh, I'm not dead, it's just that I got so much pushback on my changes that I found it much easier to push a tiny minimal thing useful for other not-use-flags things, describe the rest, and hope other people reimplement it. I tried pushing use-flags into master since at least 2015, and the best I could get in was pkgs/top-level/config.nix... Which, while nice, is still inferior to splicing-callPackages. But, yes, splicing is not particularly compatible with "traditional" overrides and overlays. Which is sad. On the other hand, today I ran nix-env -qaP -f . --out-path on Nixpkgs and it took >24G of memory to evaluate 😱 SLNOS switched to splicing in 2019, and it takes at least 2x less memory to evaluate now (in fact, I didn't know Nixpkgs took that much before today, since I wasn't using Nixpkgs much for a while).

So, if you are working on this without me, Thank You! Please, continue.
I do plan to return to this eventually, I think, because I now have some projects that would benefit from using more vanilla Nixpkgs with public build caches and such.

In other news, "wait for it to be implemented by others" also worked in a bit ironic way for #49862. Unfortunately the actual thing I wanted it for is still not implemented in master 5 years later, and having it in SLNOS and not having in NixOS is really annoying, so I updated it today to hopefully reach a compromise there. Wink-wink, it would be nice if somebody looked at it and eventually merged it.

Reviving of #75389 would probably be next.

Not at all relevant to the PR, but have you thought of making SLNOS public, and usable as a nix flake import? If it's still the same structure as NixOS users should be able to replace the nixpkgs input with the SLNOS one to use SLNOS.

@WillPower3309
Copy link
Copy Markdown
Contributor

WillPower3309 commented Jul 18, 2023

Also, worth noting that nix modules would be a huge quality of life improvement to getting this implemented

@roberth
Copy link
Copy Markdown
Member

roberth commented Jul 18, 2023

Also, worth noting that nix modules would be a huge quality of life improvement to getting this implemented

I don't think this has developed beyond a proof of concept and Eelco is currently participating in the package modules working group instead.

@infinisil infinisil added the 1.severity: significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. label Sep 1, 2023
@nyabinary
Copy link
Copy Markdown
Contributor

Eh, I'm not dead, it's just that I got so much pushback on my changes that I found it much easier to push a tiny minimal thing useful for other not-use-flags things, describe the rest, and hope other people reimplement it. I tried pushing use-flags into master since at least 2015, and the best I could get in was pkgs/top-level/config.nix... Which, while nice, is still inferior to splicing-callPackages. But, yes, splicing is not particularly compatible with "traditional" overrides and overlays. Which is sad. On the other hand, today I ran nix-env -qaP -f . --out-path on Nixpkgs and it took >24G of memory to evaluate 😱 SLNOS switched to splicing in 2019, and it takes at least 2x less memory to evaluate now (in fact, I didn't know Nixpkgs took that much before today, since I wasn't using Nixpkgs much for a while). So, if you are working on this without me, Thank You! Please, continue. I do plan to return to this eventually, I think, because I now have some projects that would benefit from using more vanilla Nixpkgs with public build caches and such. In other news, "wait for it to be implemented by others" also worked in a bit ironic way for #49862. Unfortunately the actual thing I wanted it for is still not implemented in master 5 years later, and having it in SLNOS and not having in NixOS is really annoying, so I updated it today to hopefully reach a compromise there. Wink-wink, it would be nice if somebody looked at it and eventually merged it. Reviving of #75389 would probably be next.

I think, personally, use-flags would be extremely useful, so I look forward to this being potentially revived in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.severity: significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. 2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: stdenv Standard environment 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.