../../_images/used-the-nix-to-build-the-nix.png

Use Nix to Build Nix#

Imagine you were using Nix’s C Bindings to prototype little programs that use Nix, but you really wanted to use nix_get_attr_byname_lazy which was only introduced in 3d777eb37f. What would you do? Well it turns out, you can just use Nix to build the latest version of the Nix bindings.

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
    nix-latest.url = "github:nixos/nix";
  };

  outputs = { self, nixpkgs, nix-latest }: let
    pkgs = nixpkgs.legacyPackages.aarch64-darwin;
    nix = nix-latest.packages.aarch64-darwin;
  in {
    devShells.aarch64-darwin.default = pkgs.mkShell {
      nativeBuildInputs = [
        nix.nix-expr-c
        nix.nix-store-c
        nix.nix-util-c
      ];
    };
  };
}

github:nixos/nix refers to the flake.nix file living in the root directory of nixos/nix. It provides Nix’s C bindings, and referencing it directly allows you to use the latest version of the C bindings, even if they haven’t been released yet.

Using this technique, I was able to build a simple Nix repl using Odin and Nix’s C bindings:

$ nix develop

$ odin run . -- "builtins.nixVersion"
"2.33.0pre"

$ odin run . -- "(import <nixpkgs> {}).superTuxKart.meta"
{
  unsupported: a thunk
  longDescription: a string
  name: a thunk
  mainProgram: a string
  license: a thunk
  homepage: a string
  unfree: a thunk
  maintainers: a thunk
  available: a thunk
  broken: a thunk
  description: a string
  insecure: a thunk
  outputsToInstall: a thunk
  changelog: a thunk
  position: a thunk
  platforms: a thunk
}

$ odin run . -- "(import <nixpkgs> {}).superTuxKart.meta.longDescription"
"SuperTuxKart is a Free 3D kart racing game, with many tracks,
characters and items for you to try, similar in spirit to Mario
Kart.
"

If you want to try out this repl or get started with the Nix C bindings quickly, I posted all my code here: EliasPrescott/igloo. Thanks for reading!