this post was submitted on 17 Nov 2023
0 points (50.0% liked)

Nix

10 readers
1 users here now

founded 1 year ago
MODERATORS
 

I've been seeing that nix develop takes a very long time on large projects, and I believe it's due to the whole folder being copied to the store.

nix-shell doesn't have this problem, but I need flakes specifically because they allow to have runtime libraries, which shell doesn't seem to support. (Translating flake.nix to a shell.nix exactly has different execution results.)

What can I do? I've tried putting the flake.nix on an empty subfolder, and it solves it, but it's extremely tedious and clunky.

top 4 comments
sorted by: hot top controversial new old
[–] [email protected] 0 points 1 year ago

I believe it's due to the whole folder being copied to the store.

Yep. There's work ongoing to alleviate this but for now it's a fundamental problem with flakes.

but I need flakes specifically because they allow to have runtime libraries, which shell doesn't seem to support. (Translating flake.nix to a shell.nix exactly has different execution results.)

I don't understand. There's nothing you can do with nix develop that you can't do with nix-shell. What do you mean "allow to have runtime libraries"? That's just buildInputs, which is the same regardless of flakes.

[–] [email protected] 0 points 1 year ago

Not a solution, but they're working on not requiring flakes to copy the whole source directory to the store.

[–] [email protected] 0 points 1 year ago

Have you added your flake.nix to your repo? When its not in the repo it does seem to do some copying, whereas if its checked in its pretty fast.

[–] [email protected] 0 points 1 year ago

One can have a shell.nix that uses the flake.nix in a subdir. Here's how one can do this:

in shell.nix:

let
  lock = builtins.fromJSON (builtins.readFile ./nix/flake.lock);
  flake-compat = fetchTarball {
    url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
    sha256 = lock.nodes.flake-compat.locked.narHash;
  };

  src = builtins.path {
    path = ./nix;
    name = "source";
  };
in
(import flake-compat { inherit src; }).shellNix

in ./nix/flake.nix:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
    flake-compat = {
      url = "github:edolstra/flake-compat";
      flake = false;
    };
  };

  outputs = { self, nixpkgs, flake-utils, flake-compat }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = ((import nixpkgs) {
          inherit system;
        }).pkgs;
      in
      devShell = pkgs.mkShell {
        nativeBuildInputs = [ pkgs.hello ];
      };
    )
}

Or whatever your flake is. Mostly important that we have flake-compat.

Then do a nix flake update and ensure the nix/flake.lock file exists. At that point nix-shell (in the repo root) will start working but will use the nix/flake.nix content, and only copy files in nix/ into the store. This does limit to some extent what the flake can do, but for many devShell uses it's sufficient.