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.

  • 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.