-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Provide builtins.currentSystem as a input to flakes or make system a parameter #3843
Comments
cc @zimbatm who is involved in flake-utils |
Not passing in
|
There are multiple usability issues with the current design: The list of supported systems is currently internal to the flake. As a flake author, it is useful to be able to specify which systems are supported. As a flake user, it means that it is not possible to change that list without forking the repository. Especially once the flake ecosystem starts to grow, it will quickly become prohibitive to introduce new platforms. The amount of boilerplate that is needed to specify all the permutations of systems for all the derivations. That's why I wrote flake-utils, to make that usage a bit less cumbersome. The outputs are mixing both system-dependent and independent keys so it's not as easy as passing the Typing Each flake ends-up re-initializing nixpkgs. This adds to the boilerplate and evaluation time. One possibility would be to introduce a new {
description = "Usability flakes";
systems = [ "x86_64-linux" "x86_64-darwin"];
inputs = {}; # nothing changes here
# system-independent outputs
exports = inputs: {
nixosConfiguration = {};
overlay = final: prev: {};
lib = {};
};
# system-dependent outputs
outputs = system: { self, nixpkgs, ... }@inputs:
let
# I don't have a good idea to avoid that boilerplate
pkgs = import nixpkgs {
# Notice that the overlay is accessible via `self`
overlays = [ self.overlay ];
inherit system;
};
in
{
packages.hello = pkgs.hello;
apps = {};
};
} One of the use-case that this design prevents is combining the derivations of multiple systems. This is for example if you want to create a release tarball that includes multiple architectures. In practice, that kind of construct is quite difficult to build outside of CI systems which have all the archs attached as remote builders. |
Another possibility is that |
Could we recognise the usefulness of ternary logic known-good/known-broken/unsure? The less overhead there is in checking whether something never-tried works due to upstream efforts, the better information we will have available. |
The original RFC states:
Is my assumption correct, that the idea of exposing I'm looking for exactly that use case. I'd like to expose a function that produces a python derivation, given a set of constraints.
With this trick, it's already possible to build constructs which allow passing arguments (kind of). Why not support it properly? |
No, you can definitely have library functions as flake outputs. You just can't call them from the command line.
See my comment above. Having said that, the |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flakes-with-unfree-licenses/9405/1 |
Flake outputs are a mixture of system-dependent and system-independent sets, and flake-utils doesn't do much to distinguish one from the other. Because of that, the `age` NixOS module currently has to be acessed as `agenix.nixosModules.${system}.age`, rather than the documented `agenix.nixosModules.age`. To remedy that, (conceptually) split `outputs` in two, let flake-utils handle the system-dependent half, and merge them to form the actual outputs. The names for the two halves were taken from [1]. Since someone may already be using the current paths, use the singular `nixosModule` output, so it can be accessed as `agenix.nixosModule`. [1]: NixOS/nix#3843 (comment)
Flake outputs are a mixture of system-dependent and system-independent sets, and flake-utils doesn't do much to distinguish one from the other. Because of that, the `age` NixOS module currently has to be acessed as `agenix.nixosModules.${system}.age`, rather than the documented `agenix.nixosModules.age`. To remedy that, (conceptually) split `outputs` in two, let flake-utils handle the system-dependent half, and merge them to form the actual outputs. The names for the two halves were taken from [1]. [1]: NixOS/nix#3843 (comment)
I have similar problem as @DavHau, I'd like to give users of my flake the ability to compile firmware from the command line. The ideal UX is that one would write a config file, describing the build for the build system of the original project and then a derivation would be built, which would contain just the resulting What's the alternative? |
What format is the config file in? |
it's Kconfig, the kernel like build config |
I wrote a proposal without knowing about this issue. @Mic92 pointed me to it later on and it's interesting to observe that I've come to the same conclusions. |
I strongly support the idea of making the I think the current design has a really good thing though, in that it’s conceptually very simple (the only part of the Nix codebase that has to know about the notion of a flake “system” is the cli shortcut that expands (commenting here on @domenkozar's doc because I can't comment inline on it)
I guess you'd need a way to override the
Then that leaves the problem that “The list of supported systems is currently internal to the flake” (Edit: you use
Maybe it’s the case (need to think it a bit more), but this only holds as long as Nix can generate a system-independent lockfile (because it would be pretty bad if the lockfile couldn’t be shared between two different systems)
That bit isn't really clear to me: If
I don’t think it’s really easier to parallelize this than the current version. The blocker in both cases is that the evaluator isn’t reentrant. |
Maybe a (relatively) small change to solve the problem of systems being hardcoded in a flake (which might also solve other issues) would be to allow raw Nix values as input for a flake (this shouldn’t mess-up caching as long as these values end-up in the lockfile). Then we could have a convention that flakes accept a That does in a way add yet-more-convention and doesn’t do anything for reducing the boilerplate so I’m not sure it’s a good idea as-it-is, but there might be something to build on top of that. |
Thanks for putting it so succinctly!
That's because it pushes most of the questions to the writer of the flake. I consider that a con, because things have to be implemented over and over again.
It wouldn't be an output, but you'd declare it as a setting for the input itself - evaluating the same input for different systems. I'll update the document to clarify this.
It gives the space for warning the user that the system isn't supported by the flake, instead of getting an attribute error. That seems quite an improvement for the experience.
Looking at the lockfiles (there's, unfortunately, no documentation about them), what does
It would mean you can evaluate the flake for all given systems, for example on a CI to make sure everything evaluates.
It's parallelizable because one needs to pass system as an input, so when evaluating for more than one system, that's one evaluation per system.
That will relative flakes would really go a long way with modularity. I'd still make
Yes, this design change is "convention over configuration" applied to dealing with |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
I agree with the gist of this change. The larger issue though is Flakes is constantly lagging behind idioms in Nixpkgs that have been polished over the years. For example:
We could incorporate all this stuff in Nix for Flakes, but that leaves Flakes quite brittle when we can and do refine this stuff from time to time in Nixpkgs. Or maybe we should implement more of Flakes in Nix. Factoring out |
Maybe the
That's basically correct. The flake file format doesn't impose a lot of requirements on what the output attributes of a flake are. Thus it can accommodate whatever idioms regarding systems/platforms we may come up with in the future. (This is also why we shouldn't have a OTOH, various tools can define "well-known" flake output attributes, e.g.
The semantics of those attributes are determined by the tools that operate on them. You can't just change the meaning of |
Lock files are documented here: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html#lock-files
The current hydra-evaluator is already parallel. Having to deal with a |
I understand what you are arguing for, but I am confused because to me it seems like this might at odds with the goals of nix flakes as declared in the abstract of the RFC
So "standard structure" is indeed only to be understood as "something to manage inputs / lockfile" as @Ericson2314 put it above? |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/why-is-arg-and-argstr-incompatible-with-flakes/27800/2 |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
I'm sort of running into this. I'm new to nix, and flakes especially, but I'm just trying to create a simple flake which just downloads, aggregates, and manages all of my editor plugins (i.e. vim/neovim plugins that are each merely git repositories of interpreted vim/lua scripts). Using a flake sounds nice because I can: list/specify all of my plugins declaratively within a single/simple So that's my use-case, although take it with a grain of salt as I only started using and migrating my packages to nix last week. |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476/1 |
Should I open an issue for those?
And somewhat this one too?
In practice this is what happens already. I'm pretty sure that not everything relying on While the goal is noble, either this means developers have to be too narrow and ignore plausibly working situations (“I haven't built this tool for anything else than I've talked about it with multiple people that know flakes better than I do, and no one was able to answer me: “What does Is it the system that the thing should be built on? If so, I'm not sure the semantics here are correct. Is it the system the thing should be running on? If so, would a U-Boot build for e.g. an AArch64 system only be in Here I'm not even talking about the "middle steps" of cross-compilation. Or about unconventional outputs like WASM, HTML pages, fonts, images, PDFs, GBA ROMs. Even the manual section for the format doesn't really say:
[B]uilt for is the best keywords we have for this. I might have missed something, but assuming I want to use Flakes to provide a U-Boot, I have to either lie about what the thing is built for, or somehow have something like this:
This ends-up meaning the default output cannot be used, and I have to provide clunky instructions that vary depending on the system the user happens to be using. Instead when So in practice, the current "arbitrary" values for |
FWIW people seem to usually use
In practice I believe that this is implicitly the semantics because of e.g. Nixpkgs and |
I debated linking to that or the
I believe the And anyway still comes to the same conclusion: you're pushing tracking an ambiant automatically discoverable detail (the current system) to the end-user. (Yes, I believe we agree here, I simply wanted to make it clear to others.) |
Apologies for my literal interpretation. We have
Note that these are not the kind of impurity that would prevent caching as they are still controlled by Nix itself, and such a bool is unlikely to end up in a
That's for |
I really like the perSystem function roberth suggested last year, and have been using that approach in my own flakes successfully for a few months now. It feels very clean, and you can easily be backwards compatible with the standard flake schema by calling perSystem to create it. Has anyone tried to work cross-compiles into this? I guess an attrset passed to perSystem with the host/target rather than just a string system? |
Just a tiny message to remind a comment above saying that it would be great to provide meta information to say if a program compiles for a given plateform, does not compiled (e.g. binary not available), or **not tested** (it may or may not work), to avoid unecessary errors.
|
@tobiasBora The proposed Nixpkgs "problem" infrastructure could perhaps be used for this purpose. It wasn't specifically design for this, but it seems that it could be made to work well outside Nixpkgs as well. It's currently in development at: |
I've renamed this issue to hint at an alternative that is less contradicting to the requirements suggested in the first response. Suggestions have been made to solve this by
We can change this back to a discussion about a single solution if you prefer, but otherwise I think this issue is representative of roughly the requirements
|
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
I would love never having to lookup the correct string for my system ever again (an absurd bit of busywork). Whatever you need to do to make this happen, go ahead. |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-09-25-nix-team-meeting-minutes-89/33489/1 |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flake-design-of-system-os/36654/4 |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flake-design-of-system-os/36654/7 |
- Simplifies the whole thing due to not having to mess with `system`, see NixOS/nix#3843 - Makes the lockfile _way_ smaller, see NixOS/nix#7730
- Simplifies the whole thing due to not having to mess with `system`, see NixOS/nix#3843 - Makes the lockfile _way_ smaller, see NixOS/nix#7730
Is your feature request related to a problem? Please describe.
Right now one has to explicitly define system in flake outputs.
The nix flake itself already comes with boiler code like this:
I think having to use that much code hurts portability of the ecosystem because people
will only specify the minimum and there seems no easy way of overriding it without changing the
flake itself.
Describe the solution you'd like
Describe alternatives you've considered
Use boilercode in every project or rely on external libraries like https://github.com/numtide/flake-utils
If someone needs to explicitly specify platforms i.e. to build packages for different architectures with hydra this should be still possible.
The text was updated successfully, but these errors were encountered: