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

nix flake check breaks on IFD in multi-platform flake #4265

Open
Kha opened this issue Nov 16, 2020 · 27 comments
Open

nix flake check breaks on IFD in multi-platform flake #4265

Kha opened this issue Nov 16, 2020 · 27 comments
Labels

Comments

@Kha
Copy link
Contributor

Kha commented Nov 16, 2020

Describe the bug

Given the following flake

{
  description = "A very basic flake";

  inputs.flake-utils.url = github:numtide/flake-utils;

  outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system:
    with nixpkgs.legacyPackages.${system}; {
      checks.hello = import (writeText "hi" "hi");
    });
}

nix flake check will fail with

error: --- Error --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
a 'aarch64-linux' with features {} is required to build '/nix/store/xqdq3nrw9s3f7vpn1zzsryhsqkh23634-hi.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
(use '--show-trace' to show detailed location information)

because while it does not build checks of foreign platforms, it still tries to evaluate them, which with IFDs can lead to building after all.

Expected behavior

nix flake check should catch uses of IFD and perhaps print a warning but continue to check other parts. Alternatively, there could be a check attribute or cmdline flag that disable evaluation on foreign platforms.

@Kha Kha added the bug label Nov 16, 2020
@matthewbauer
Copy link
Member

A hacky workaround is just to use nixpkgs.legacyPackages.x86_64-linux for evaluation and nixpkgs.legacyPackages.${system} for the actual derivation. Usually you're just doing some preprocessing so it works out to evaluate on one system and build on another.

matthewbauer added a commit to matthewbauer/bauer that referenced this issue Dec 1, 2020
@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/how-to-use-flakes-with-ifd/10300/2

@nrdxp
Copy link

nrdxp commented Apr 10, 2021

FWIW, we have actually be using this "bug" to detect surprising or unwanted IFD in devos. Maybe, after fixing this we could make some sort of library or builtin function, such as isIFD, in order to continue detecting it in unwanted places 😄

Or maybe a flag to nix flake check such as --fail-on-ifd that preserves the current behavior.

@colonelpanic8
Copy link

this problem also applies to nix flake show

@colonelpanic8
Copy link

Hmmm. It seems like IFD definitely needs to be allowed in e.g. defaultPackages. Does anyone have any ideas about what the right solution here is?

minimal added a commit to minimal/dotfiles that referenced this issue Sep 28, 2021
remove hm build completely

Checks fail cross platform due to NixOS/nix#4265
@nixinator
Copy link
Member

just for reference the iohk cardano-node flake also exhibits the same 'problem/issue/feature'.

nix flake show github:input-output-hk/cardano-node

the-mikedavis referenced this issue in tspm-io/tspm Mar 8, 2022
Here we strip out all other flake dependencies and use similar
functions to edolstra/dwarffs and numtide/flake-utils to build
a custom flake output that takes system into account. It appears
from my bug hunting that the 'nix flake check' failure was introduced
with '{ path = "metadata"; }', which uses `builtins.hashFile` on
a built derivation, which, if I understand it correctly, is
recursive Nix. That appears to mess with the system that
builtins.hashFile needs somehow, so the builder for aarch64-linux
fails.
@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/nix-flake-show-fails-when-the-flake-provides-packages-for-other-platforms/18726/2

@yajo
Copy link
Contributor

yajo commented May 16, 2022

A hacky workaround is just to use nixpkgs.legacyPackages.x86_64-linux for evaluation and nixpkgs.legacyPackages.${system} for the actual derivation.

How can you know that the machine you're running on is x86_64-linux? Maybe you're on an aarch64-linux and evaluating a derivation for x86_64-linux.

@anka-213
Copy link

I wish there was a way to say that an IFD is platform independent (probably necessitating a hash of the expected resulting nix expression). That way you could handle other platforms while still evaluating on the local platform. It could probably work somewhat similarly to other fixed output derivations like file downloads.

@peterbecich
Copy link
Contributor

peterbecich commented Jun 6, 2023

Thanks

I see the same error with Nix 2.16

$  nix flake check github:hasktorch/hasktorch   
...
error: a 'x86_64-darwin' with features {} is required to build
'/nix/store/h3prp5ng7ghxcv9xcyf0bdkrjnvclilr-alex-3.2.4-r1-src.drv',
but I am a 'x86_64-linux' with features

I see that repo uses haskell.nix. I have raised the same issue there: input-output-hk/haskell.nix#1825

Perhaps there are two overlapping issues here both causing nix flake check to fail; something with IFD in nix itself, and something specifically in haskell.nix.

@peterbecich
Copy link
Contributor

@DavHau , thanks for providing this example
#4265 (comment)

With Nix 2.16, the result is:

$  nix flake check
warning: The check omitted these incompatible systems: aarch64-darwin, aarch64-linux, x86_64-darwin
Use '--all-systems' to check all.

and

 $ nix flake check --all-systems
error:
       … while checking flake output 'checks'

         at /nix/store/dbppismymjc6382g4v6d6sb99pjby37b-source/lib.nix:73:15:
....

       error: a 'aarch64-darwin' with features {} is required to build 
'/nix/store/fqbrhssl2h3064277p8a9yjz8m4qsskc-hi.nix.drv', 
but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test, uid-range}

So this is good news.

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/help-understanding-templates-haskell-nix/30990/1

@zmrocze
Copy link

zmrocze commented Dec 12, 2023

I remember this issue since forever. Can we add a simple flag filtering outputs for just one system? As simple partial workaround, like:

$ nix flake show --system=x86_64-linux
├───checks
│   └───x86_64-linux
│       ├───"homeConfiguraton_zmrocze@omen": derivation 'home-manager-generation'
│       └───pre-commit: derivation 'pre-commit-run'
├───devShells
│   └───x86_64-linux
│       ├───default: development environment 'nix-shell'
├───homeConfigurations: unknown
└───nixosConfigurations
    ├───omen: NixOS configuration

This is still helpful for local development, i.e. when I'm including all outputs from some dynamically defined flake and I don't know the attribute names.

@klarkc
Copy link

klarkc commented Jan 12, 2024

The problem was expected to be resolved in version 2.16, but it persists in version 2.19.1. The issue occurs specifically during nix flake check in haskell.nix. I don't know what steps to take to address this. My current approach involves removing support for all other systems and any form of cross-compilation.

@Dessix
Copy link

Dessix commented Jan 12, 2024

Wasn't the whole point of flakes to make cross-system management viable because Hydra couldn't manage the prior system? Removing it seems like giving up one of the primary motivators that led to inconvenience in almost every other area of functionality.

JakeHillion added a commit to JakeHillion/nixos that referenced this issue Feb 6, 2024
Using a pkgs.writeText causes an import at evaluation time instead of
just build time. This means that no host running `nix flake check` can't
check all configurations if you have mixed architectures in a flake.

For some reason I've been getting away with this. This stopped when
switching to nixos-2311. Move the known hosts with a single key into the
NixOS config directly and put the GitHub keys in a real file. These
can't go into `.knownHosts` directly as it only supports one key per
host (sigh).

Reference: NixOS/nix#4265
JakeHillion added a commit to JakeHillion/nixos that referenced this issue Feb 6, 2024
Using a pkgs.writeText causes an import at evaluation time instead of
just build time. This means that no host running `nix flake check` can't
check all configurations if you have mixed architectures in a flake.

For some reason I've been getting away with this. This stopped when
switching to nixos-2311. Move the known hosts with a single key into the
NixOS config directly and put the GitHub keys in a real file. These
can't go into `.knownHosts` directly as it only supports one key per
host (sigh).

Reference: NixOS/nix#4265
JakeHillion added a commit to JakeHillion/nixos that referenced this issue Feb 6, 2024
Using a pkgs.writeText causes an import at evaluation time instead of
just build time. This means that no host running `nix flake check` can't
check all configurations if you have mixed architectures in a flake.

For some reason I've been getting away with this. This stopped when
switching to nixos-2311. Move the known hosts with a single key into the
NixOS config directly and put the GitHub keys in a real file. These
can't go into `.knownHosts` directly as it only supports one key per
host (sigh).

Reference: NixOS/nix#4265
JakeHillion added a commit to JakeHillion/nixos that referenced this issue Feb 6, 2024
Using a pkgs.writeText causes an import at evaluation time instead of
just build time. This means that no host running `nix flake check` can
check all configurations if you have mixed architectures in a flake.

For some reason I've been getting away with this. This stopped when
switching to nixos-2311. Move the known hosts with a single key into the
NixOS config directly and put the GitHub keys in a real file. These
can't go into `.knownHosts` directly as it only supports one key per
host (sigh).

Reference: NixOS/nix#4265
korfuri added a commit to korfuri/nix-software-center that referenced this issue Apr 11, 2024
I recently added a flake for nixos-appstream-data. This allows us to
depend on that flake instead of doing an IFD to load its
default.nix.

An IFD in nix-software-center is problematic for users who use
flakes and have multiple nixos configurations with different
architectures. Because of NixOS/nix#4265
this causes `nix flake check` to fail for them.
korfuri added a commit to korfuri/nixos-appstream-data that referenced this issue Apr 11, 2024
Exposing nixos-appstream-data as a flake will allow
nix-software-center to depend on it the flake way, instead of via an
IFD. Having nix-software-center use an IFD is problematic because
users of that package may run into NixOS/nix#4265

Adding this flake does not cause an API change for non-flake users.
korfuri added a commit to korfuri/nixos-appstream-data that referenced this issue Apr 11, 2024
Exposing nixos-appstream-data as a flake will allow
nix-software-center to depend on it the flake way, instead of via an
IFD. Having nix-software-center use an IFD is problematic because
users of that package may run into NixOS/nix#4265

Adding this flake does not cause an API change for non-flake users.
korfuri added a commit to korfuri/nix-software-center that referenced this issue Apr 11, 2024
I recently added a flake for nixos-appstream-data. This allows us to
depend on that flake instead of doing an IFD to load its
default.nix.

An IFD in nix-software-center is problematic for users who use
flakes and have multiple nixos configurations with different
architectures. Because of NixOS/nix#4265
this causes `nix flake check` to fail for them.

Note that users of nix-software-center that do not rely on the flake
will still need an IFD. I'm not aware of a better way (other than
upstreaming both in nixpkgs).
korfuri added a commit to korfuri/nix-software-center that referenced this issue Apr 11, 2024
I recently added a flake for nixos-appstream-data. This allows us to
depend on that flake instead of doing an IFD to load its
default.nix.

An IFD in nix-software-center is problematic for users who use
flakes and have multiple nixos configurations with different
architectures. Because of NixOS/nix#4265
this causes `nix flake check` to fail for them.

Note that users of nix-software-center that do not rely on the flake
will still need an IFD. I'm not aware of a better way (other than
upstreaming both in nixpkgs).
korfuri added a commit to korfuri/nix-software-center that referenced this issue Apr 11, 2024
I recently added a flake for nixos-appstream-data. This allows us to
depend on that flake instead of doing an IFD to load its
default.nix.

An IFD in nix-software-center is problematic for users who use
flakes and have multiple nixos configurations with different
architectures. Because of NixOS/nix#4265
this causes `nix flake check` to fail for them.

Note that users of nix-software-center that do not rely on the flake
will still need an IFD. I'm not aware of a better way (other than
upstreaming both in nixpkgs).

TODO: point this back to snowfallorg's repo after
snowfallorg/nixos-appstream-data#1 is merged.
korfuri added a commit to korfuri/nix-software-center that referenced this issue Apr 15, 2024
I recently added a flake for nixos-appstream-data. This allows us to
depend on that flake instead of doing an IFD to load its
default.nix.

An IFD in nix-software-center is problematic for users who use
flakes and have multiple nixos configurations with different
architectures. Because of NixOS/nix#4265
this causes `nix flake check` to fail for them.

Note that users of nix-software-center that do not rely on the flake
will still need an IFD. I'm not aware of a better way (other than
upstreaming both in nixpkgs).

Ref: snowfallorg/nixos-appstream-data#1
korfuri added a commit to korfuri/lanzaboote that referenced this issue Jun 9, 2024
Before this commit, we use cranelib.cleanCargoSource[1] to filter
files in the ./rust/uefi directory. This prevents some rebuilds when
files that do not contribute to the build are changed (e.g. a
README). However, this causes lanzaboote's flake.nix to contain an
IFD[2]. This seems to be unavoidable when using cleanCargoSource[3].

Why this is useful anyway:

Since `nix flake check` must check all outputs of the given flake,
it's not possible to split a flake check across multiple builder
machines. This means that `nix flake check` without `--no-build` can
only work if the builder machine has support to build for all
architectures present in that flake's `nixosConfigurations`
output. This is achievable with binfmt emulation, but excruciatingly
slow, especially for use-cases like "run nix flake check in CI". In
practice this means that a flake containing nixosConfiguration outputs
with different `system` attributes can generally only be `nix flake
check`'d with `--no-build`. See [4] for a long discussion on this.

Unfortunately, this affects flakes using Lanzaboote transitively. So
any flake containing Lanzaboote-enabled nixosConfigurations (like
mine[5]) are not be able to use `nix flake check --no-build`.

This commit corrects this by removing the IFD. This can be tested
with:

$ nix store gc   # to ensure IFD paths are not cached
$ nix flake check --no-build github:nix-community/lanzaboote  # fails
$ nix store gc
$ nix flake check --no-build github:korfuri/lanzaboote  # succeeds

[1] https://crane.dev/API.html#cranelibfiltercargosources
[2] https://nix.dev/manual/nix/2.22/language/import-from-derivation
[3] ipetkov/crane#612
[4] NixOS/nix#4265
[5] https://gitlab.com/korfuri/infra/-/blob/77635232eb65e877d8b79eb98f6264381231c20c/flake.nix
donovanglover added a commit to donovanglover/nix-config that referenced this issue Jun 21, 2024
This fixes an issue where previously the derivation had to be evaluated
before importing the base16 scheme, thus causing `nix flake check` to
fail when multi-platform support was added.

See: NixOS/nix#4265
@sellout
Copy link
Contributor

sellout commented Nov 15, 2024

My current workaround for this is to use the https://github.com/nix-systems/nix-systems pattern in the flake and then run

nix flake show --override-input systems github:nix-systems/aarch64-darwin

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

No branches or pull requests