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.
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.
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 withnix-shell
. What do you mean “allow to have runtime libraries”? That’s justbuildInputs
, which is the same regardless of flakes.Not a solution, but they’re working on not requiring flakes to copy the whole source directory to the store.
One can have a
shell.nix
that uses theflake.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 thenix/flake.lock
file exists. At that pointnix-shell
(in the repo root) will start working but will use thenix/flake.nix
content, and only copy files innix/
into the store. This does limit to some extent what the flake can do, but for manydevShell
uses it’s sufficient.