Nix 2.26 released

Hi,

I’m pleased to announce the availability of Nix 2.26. It is available from https://releases.nixos.org/?prefix=nix/nix-2.26.0/ .

  • Support for relative path inputs #10089

    Flakes can now refer to other flakes in the same repository using relative paths, e.g.

    inputs.foo.url = "path:./foo";
    

    uses the flake in the foo subdirectory of the referring flake. For more information, see the documentation on the path flake input type.

    This feature required a change to the lock file format. Previous Nix versions will not be able to use lock files that have locks for relative path inputs in them.

  • Flake lock file generation now ignores local registries #12019

    When resolving indirect flake references like nixpkgs in flake.nix files, Nix will no longer use the system and user flake registries. It will only use the global flake registry and overrides given on the command line via --override-flake.

    This avoids accidents where users have local registry overrides that map nixpkgs to a path: flake in the local file system, which then end up in committed lock files pushed to other users.

    In the future, we may remove the use of the registry during lock file generation altogether. It’s better to explicitly specify the URL of a flake input. For example, instead of

    {
      outputs = { self, nixpkgs }: { ... };
    }
    

    write

    {
      inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
      outputs = { self, nixpkgs }: { ... };
    }
    
  • nix copy supports --profile and --out-link #11657

    The nix copy command now has flags --profile and --out-link, similar to nix build. --profile makes a profile point to the
    top-level store path, while --out-link create symlinks to the top-level store paths.

    For example, when updating the local NixOS system profile from a NixOS system closure on a remote machine, instead of

    # nix copy --from ssh://server $path
    # nix build --profile /nix/var/nix/profiles/system $path
    

    you can now do

    # nix copy --from ssh://server --profile /nix/var/nix/profiles/system $path
    

    The advantage is that this avoids a time window where path is not a garbage collector root, and so could be deleted by a concurrent nix store gc process.

  • nix-instantiate --eval now supports --raw #12119

    The nix-instantiate --eval command now supports a --raw flag, when used
    the evaluation result must be a string, which is printed verbatim without
    quotation marks or escaping.

  • Improved NIX_SSHOPTS parsing for better SSH option handling #5181 #12020

    The parsing of the NIX_SSHOPTS environment variable has been improved to handle spaces and quotes correctly. Previously, incorrectly split SSH options could cause failures in commands like nix-copy-closure, especially when using complex SSH invocations such as -o ProxyCommand="ssh -W %h:%p ...".

    This change introduces a shellSplitString function to ensure that NIX_SSHOPTS is parsed in a manner consistent with shell behavior, addressing common parsing errors.

    For example, the following now works as expected:

    export NIX_SSHOPTS='-o ProxyCommand="ssh -W %h:%p ..."'
    

    This update improves the reliability of SSH-related operations using NIX_SSHOPTS across Nix CLIs.

  • Nix is now built using Meson

    As proposed in RFC 132, Nix’s build system now uses Meson/Ninja. The old Make-based build system has been removed.

  • Evaluation caching now works for dirty Git workdirs #11992

Contributors

This release was made possible by the following 45 contributors:

64 Likes

@roberth has an open PR to build it in nixpkgs. Track that to see when it’ll be available for use!

4 Likes

That’s a huge release !! Thanks to everyone who made it possible.

Flake lock file generation now ignores local registries

I am quite happy to see that hurdle considered. Looking for nixpkgs in the registry made explaining flakes harder to newbies as I had mentioned in add nixpkgs as input of "trivial" template by teto · Pull Request #53 · NixOS/templates · GitHub (while being tricky as well).

Evaluation caching now works for dirty Git workdirs

That represents 90% of my nix usage so quite curious to see how much faster it gets :slight_smile:

8 Likes

Does this also work if the relative path points to a git submodule which may or may not be available as an actual directory?

1 Like

It should work if the submodule is fetched, i.e. if you’re using ?submodules=1 on the parent flake.

2 Likes

Hey!

Previously I was able to update the inputs from relatively imported flake.nix inside a monorepo by either:

$ nix flake update basic-go-web-app

or by using --override-input basic-go-web-app ./services/basic-go-web-app/ in the nixos-rebuild to always follow the latest changes from the local second flake file and bypassing the lock file.

Now when I use either of them it fails to run:

$ nix --version
nix (Nix) 2.26.0
$ nix flake update basic-go-web-app
warning: Git tree '/Users/onnimonni/Projects/example-nixos-server' is dirty
warning: updating lock file '"/Users/onnimonni/Projects/example-nixos-server/flake.lock"':
• Updated input 'basic-go-web-app':
    'path:./services/basic-go-web-app/?lastModified=1&narHash=sha256-u/7nvhOP4IIccK8AFuBtd529fC5163IjyBfv6z5GRUE%3D' (1970-01-01)
  → 'path:./services/basic-go-web-app/'
warning: Git tree '/Users/onnimonni/Projects/example-nixos-server' is dirty
$ git diff flake.lock
diff --git a/flake.lock b/flake.lock
index 9509062..f41dc51 100644
--- a/flake.lock
+++ b/flake.lock
@@ -6,15 +6,14 @@
         "go-nixpkgs": "go-nixpkgs"
       },
       "locked": {
-        "lastModified": 1,
-        "narHash": "sha256-u/7nvhOP4IIccK8AFuBtd529fC5163IjyBfv6z5GRUE=",
         "path": "./services/basic-go-web-app/",
         "type": "path"
       },
       "original": {
         "path": "./services/basic-go-web-app/",
         "type": "path"
-      }
+      },
+      "parent": []
     },
     "disko": {
       "inputs": {
$ nix run nixpkgs#nixos-rebuild -- switch --fast --flake .#rusty --target-host rusty --build-host rusty --use-remote-sudo
building the system configuration...
warning: Git tree '/Users/onnimonni/Projects/example-nixos-server' is dirty
error:
       … while updating the lock file of flake 'git+file:///Users/onnimonni/Projects/example-nixos-server'

       error: lock file contains unlocked input '{"path":"./services/basic-go-web-app/","type":"path"}'

What is the correct way to update the relative flake import?

This seems like a bug to me :thinking:

You can see roughly the same monorepo setup here as I’m using here: GitHub - onnimonni/hetzner-auction-nixos-example

And here’s the commit how I added the second flake into the project.

My remote server has nix version 2.24.11 if it matters.

Awesome!
The build system should make it a lot simpler to contribute (I would think?)
How has the development experience in IDEs been ?

Does it emit a compiler_commands.json for clangd etc…?

3 Likes

I wasted my Saturday trying to get a relative flake import working in my nixos config. What a nice coincidence to see that fix included in this release! So I just run nix flake update on my nixos system to get these updates?

I would be curious to see if it works like that for you :+1: I got the following error myself when I did it exactly like you were wondering.

1 Like

Not sure if that comment was directed at me but I was able to import a relative flake like so in my top level flake.nix:

inputs = {
    my-extra-fonts = {
      url = "path:./flakes/my-extra-fonts";
      inputs.nixpkgs.follows = "nixpkgs";
    };
};
outputs = {} @ inputs:
{
  nixosConfigurations = {
    # ....
    specialArgs = { inherit inputs };
  };
}

Probably not yet. 2.26 isn’t in nixpkgs master yet (let alone as default on nixos-unstable or something).

How has the development experience in IDEs been ?

Does it emit a compiler_commands.json for clangd etc…?

I’m embarrassed to say I haven’t bothered to try to figure IDE things out :), but I think @roberth and @l-as at least were using this successfully.

Yes, meson emits compile_commands.json in the build directory, and clangd picks that up.
So that’s just calling mesonConfigurePhase in the dev shell, and you’re set up.
We bundle a clangd in nix develop .#native-clangStdenv. I then use the vscode direnv extension to make that available to the clangd extension.

my .envrc

This could probably be done way simpler. I haven’t really changed it in ages.

watch_file flake.nix
watch_file flake.lock

# nixEnv="$(nix print-dev-env)"
nixEnv="$(nix print-dev-env .#native-clangStdenv)"
# nixEnv="$(nix print-dev-env .#hydraJobs.buildNoGc.i686-linux)"

if [[ -z $nixEnv ]]
then use_nix
else

  HOST_XDG_DATA_DIRS="${XDG_DATA_DIRS:-}"

  eval "${nixEnv:-}"

  export XDG_DATA_DIRS="${XDG_DATA_DIRS}:${HOST_XDG_DATA_DIRS}"

fi
3 Likes

Looks like this post is not mentioned in the subcategory nix-releases? I had to look a bit to find this one again:

1 Like

What’s print-dev-env

I’ve never seen that command.
Isn’t the “use Nix” directive enough ?

https://nix.dev/manual/nix/2.24/command-ref/new-cli/nix3-print-dev-env.html

I think you meant use flake from direnv, and print-dev-env is exactly what it uses underneath.

Not sure if the envvar saving could be expressed with it though.

Interesting here. Chose to do ‘usenix’ and the inner print call instead of use flake

It seems that documentation for 2.26 is missing in https://nix.dev
and also 2.26 doesn’t seem to ship with any man pages Man pages are not installed with Nix 2.26.1 · Issue #12382 · NixOS/nix · GitHub

something in the switch to meson seems to have broken things.

Oh well, that’s a bit of an anti-feature for me. I had hoped for having a system flake that would register itself (at it’s specific version) in local registry and a couple of task-specific flakes that would refer to it via local registry and define shell with some task-specific software. Rationale: keeping different source flakes versions in sync would be so much easier.
I know I’d face some problems with flake.lock in task-flakes, but a forced update (or rm flake.lock) would probably sort that out and still keep all task-flakes refer to the same nixpkgs. Effectively I want a shared flake.lock between several flakes.

Any ideas I can achieve this now? Running nix flake update at exactly the same time for all task-flakes or manually fiddling with flake.lock seem a no-go for me. So does having task-flakes refer to nixpkgs at different points of time and thus installing several versions of whatever lib out there. Building stuff locally instead of substituting it seems fine, at least for the task-flakes.

The point is to prevent pushing a broken lockfile, since no one else would have that path in their store.

You can still force it to use the local registry using the workaround provided.