Nix By Examples


The Nix Language


packaging 101


Let's imagine that we want to package a C binary, so that one can easily install it or develop on it.
int main() { 
    printf("hello world"); 
    return 0;


The first thing to do is to create a `flake.nix` file.
  description = "My own hello world";
a flake must contain an `outputs` function that takes an attribute set of at least `self` and an optional number of packages to use (here just `nixpkgs`).
  outputs = { self, nixpkgs }: 
The first thing we do here, is to create a function that we will reuse to build our package for different systems (mac and linux). This function takes one argument: `system`.
      build_for = system:
We import `nixpkgs` with the `system` that we passed as argument (same as writing `system = system;` in the second argument of `import`.
          pkgs = import nixpkgs { inherit system; };
`stdenv.mkDerivation` allows us to create a **derivation**, which is nix's term for a package.
        pkgs.stdenv.mkDerivation {
          name = "hello";
          src = self;
          buildInputs = [ pkgs.gcc pkgs.which ];
          buildPhase = "gcc -o hello ./hello.c";
          installPhase = "mkdir -p $out/bin; install -t $out/bin hello";
the `output` function must return an attribute set containing default packages for one or more platforms.
      packages.x86_64-darwin.default = build_for "x86_64-darwin";
      packages.x86_64-linux.default = build_for "x86_64-linux";


You can use `nix flake check` to make sure that the flake is correctly written.
$ nix flake check
While you can build your derivation using `nix build`, you can also directly run it using `nix run` (which will try to run `<out>/bin/<name>`).
$ nix run
hello world
Using `nix develop -i` you can open a shell that comprises the same dependencies as your build environment. (Note that `which` is accessible because we added it to the `buildInputs` of the derivation.
$ nix develop -i
$ which gcc
next: flake-utils