Skip to content
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

Flake arguments #2861

Closed
edolstra opened this issue Feb 13, 2019 · 18 comments
Closed

Flake arguments #2861

edolstra opened this issue Feb 13, 2019 · 18 comments

Comments

@edolstra
Copy link
Member

Currently, flakes are evaluated in pure mode and have no function arguments (other than the computed set of flake dependencies), so it's not possible to do things like:

  • Use builtins.currentSystem.
  • Access ~/.config/nixpkgs/{config.nix,overlays}.
  • Access command line arguments passed via --arg.

Thus we need a controlled way to pass arguments to a flake. This must not compromise hermetic evaluation or the ability to aggressively cache evaluation results. For example, the arguments passed to a flake should be unambiguously hashable to produce a cache key (such that (flakeClosureHash, argumentsHash, attributeName) uniquely determines the evaluation result).

For replacing builtins.currentSystem, however, we don't necessarily have to rely on a function argument. Instead, a flake could simply provide packages/derivations for all platforms that it supports. This is feasible thanks to laziness. For example, the nixpkgs flake would provide attributes such as packages.x86_64-linux.hello and packages.x86_64-darwin.hello rather than a single packages.hello that depends on a function argument. (This is an approach familiar from Hydra jobsets.) The nix UI can select the appropriate set automatically (e.g. nix run nixpkgs.hello will select nixpkgs.provides.packages.$system.hello.)

@edolstra
Copy link
Member Author

Will need to handle the system issue urgently at least.

@grahamc grahamc transferred this issue from another repository May 16, 2019
edolstra added a commit that referenced this issue Oct 15, 2019
A command like

  $ nix run nixpkgs#hello

will now build the attribute 'packages.${system}.hello' rather than
'packages.hello'. Note that this does mean that the flake needs to
export an attribute for every system type it supports, and you can't
build on unsupported systems. So 'packages' typically looks like this:

  packages = nixpkgs.lib.genAttrs ["x86_64-linux" "i686-linux"] (system: {
    hello = ...;
  });

The 'checks', 'defaultPackage', 'devShell', 'apps' and 'defaultApp'
outputs similarly are now attrsets that map system types to
derivations/apps. 'nix flake check' checks that the derivations for
all platforms evaluate correctly, but only builds the derivations in
'checks.${system}'.

Fixes #2861. (That issue also talks about access to ~/.config/nixpkgs
and --arg, but I think it's reasonable to say that flakes shouldn't
support those.)

The alternative to attribute selection is to pass the system type as
an argument to the flake's 'outputs' function, e.g. 'outputs = { self,
nixpkgs, system }: ...'. However, that approach would be at odds with
hermetic evaluation and make it impossible to enumerate the packages
provided by a flake.
@zimbatm
Copy link
Member

zimbatm commented Oct 17, 2019

I think this will make the adoption of new systems more difficult as each flake has a hard-coded list of supported systems. Would it be bad to add a top-level { system }: argument to flake.nix instead?

@jD91mZM2
Copy link
Member

Alternatively to @zimbatm's comment, I'd be fine with having

forAllSystems = nixpkgs.lib.genAttrs [ "x86_64-linux" "x86_64-darwin" "i686-linux" "aarch64-linux" ]

be a provided function somewhere, that could work on a series of groups. forAllSystems systems.all, forAllSystems systems.unix, idk. But I do like the idea of splitting up packages in the end

@zimbatm
Copy link
Member

zimbatm commented Jan 18, 2020

I guess if the flake depends on nixpkgs, then we could have nixpkgs export a nixpkgs.lib.forAllSystems. That way all flakes automatically gain as many systems as nixpkgs supports.

@colonelpanic8
Copy link

I realize that the issue of specifying system has (sort of) been resolved, but afaik there is still no way to pass arguments to flakes.

I guess its very hard to make arguments work with the sort of hermetic, pure environment that flakes strives to acheive. Not being able to pass any arguments is a pretty huge compromise though.

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/passing-options-to-flakes/7579/3

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/creating-an-sdimage-with-nix-build-nixpkgs/19298/1

@dpc
Copy link

dpc commented Jul 29, 2022

Can we reopen this? As things are RN, it's very hard to parametrize a flake, which seems very limiting. The use case I have at hand is - I'd like to use a flake.nix to cross-compile Rust project to different architectures in the CI (so I can build for x86/arm64, linux/mac/windows). For this I need to pass a different target (not system, as the system stays the same, AFAIU) to the Rust toolchain.

I tried to make a flake.base.nix that would be a function returning a flake, and then flake.nix would contain ((import ./flake.base.nix) { target = "x86_64-linux"; }) as a default, but this doesn't seem to work: error: file '/nix/store/jwsskhfbqniz70qkawknxvbzj9n3rxcj-source/flake.nix' must be an attribute set

I guess the last resort is to wrap the whole outputs value into something like eachDefaultSystem, but for arbitrary variables with a given set of known values (supporter targets in my case). Doesn't seem ideal, but I guess it should work. Then I could nix build .#packages.x86_64-linux.aarch64-linux.mybin etc. maybe?

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/what-would-you-like-to-see-improved-in-nix-cli-experience/24012/22

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/can-i-use-flakes-within-a-git-repo-without-committing-flake-nix/18196/33

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/how-can-we-pass-argument-to-flake-nix/30833/2

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/experimental-does-not-mean-unstable-detsyss-perspective-on-nix-flakes/32703/2

@adrian-gierakowski
Copy link

Could someone point me to an explanation on why this issue has been closed? Has it been replaced by some other issue?

I’m particularly interested in passing arguments other than system. Is this still on the roadmap?

@RyanGibb
Copy link

RyanGibb commented Sep 7, 2023

@adrian-gierakowski it seems arguments are supported by the derivation path. This doesn't support arbitrary arguments, however.

@adrian-gierakowski
Copy link

@adrian-gierakowski it seems arguments are supported by the derivation path. This doesn't support arbitrary arguments, however.

@RyanGibb could you please elaborate? An example of what’s possible would great.

something I’d like to be able to do is:

nix build|run|eval —argstr my-arg my-value

@RyanGibb
Copy link

nix build|run|eval —argstr my-arg my-value

You could create a derivation path such as nix build.#my-arg.my-value. When I say it doesn't support arbitrary arguments, I mean it doesn't support arbitrary values for arguments. You need to enumerate all the possible options. Let me know if that doesn't make sense and I can write an example flake.

Could someone point me to an explanation on why this issue has been closed? Has it been replaced by some other issue?

Perhaps #6583?

@adrian-gierakowski
Copy link

@RyanGibb thank you for clarifying and for the link

@ggPeti
Copy link
Member

ggPeti commented Jan 17, 2024

made a workaround

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

No branches or pull requests

10 participants