Site logo
Stories around the Genode Operating System RSS feed
Emery Hemingway avatar

Deploying Nim on NixOS

This article describes writing Nix expressions for building Nim projects. I use Genode/Sculpt as my daily-driver OS, but run NixOS on my hosted virtual servers. I find NixOS to be the easiest UNIX clone to configure and for what I do a container on a NixOS host is sufficient, hardware virtualization is not necessary. I wont mention Genode again, other than to say that this method allows me to write projects that I can deploy on Genode and NixOS using a common codebase.

I will use my Blobsets project as an example because it contains a server and client for both Genode and POSIX.

This method locally defines some sort of Nix package, and does not involve the Nix package collection, it simply adds a file named default.nix to the root of the Nim project. To install the project on a NixOS host the project source is cloned and the Nix expression file is passed directly to nix-env

 git clone ... my_project
 nix-env -f my_project/default.nix -i

Easy, right?

The details are in the default.nix file, which I will annotate inline:

 with import <nixpkgs> { };
   # Import Nixpkgs from the current profile into the file's
   # global scope. This allows declarations like 'stdenv' to be
   # used as if this was a function with named arguments ({stdenv, ... }:).

 stdenv.mkDerivation {
   # reuse the normal Nixpkgs utilities

   name = "blobsets-0";

   src = ./.;
     # copy the local directory to the Nix store as the 'src' input

   cbor = fetchFromGitHub {
     # Peg the Nimble dependencies in this derivation scope rather
     # than worry about packaging them for Nixpkgs

     owner = "ehmry";
     repo = "nim-cbor";
     rev = "v0.5.2";
     sha256 = "0fh8vriad6nvjl3fxl2b62bk7y4z1hx90527a530nln5g1cj9z8f";

   siphash = fetchFromGitHub {
     owner = "ehmry";
     repo = "nim-siphash";
     rev = "v0.1.0";
     sha256 = "1z4xm3ckygw8pmn9b6axdk65ib1y5bgwa3v1dbxamvhjmyfr62w4";

   buildInputs = [ nim pcre ];
   NIX_LDFLAGS = [ "-lpcre" ];
     # This example uses PCRE so link to the library rather
     # than use dynamic loading, this way Nix will catch the
     # dependency when it scans the output binary

   buildPhase = ''
     nim c --path:$cbor/src --path:$siphash/src -d:release src/blobset.nim
     # Nim will need some libraries to build this project, so they've
     # been declared in the derivation scope and passed to the compiler
     # with the '--path' flag

   installPhase = "install -Dt $out/bin src/blobset";
     # Override the installPhase because the default will simply
     # invoke 'make install'