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.

  • NateDevCSharp@alien.top
    cake
    B
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 year ago

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

  • pr06lefs@alien.top
    cake
    B
    link
    fedilink
    English
    arrow-up
    1
    ·
    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.

  • ElvishJerricco@alien.topB
    link
    fedilink
    English
    arrow-up
    1
    ·
    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.

  • jmesmon@alien.topB
    link
    fedilink
    English
    arrow-up
    1
    ·
    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.