Pre-building the sqlite binary for org-roam on NixOS

Are you an org-roam user who also uses NixOS and are annoyed waiting for org-roam (or technically emacsql) to compile its sqlite binary?

Then do something like this:

  1. pre-build the executable using the wonders of nix
  2. either inject the newly built package into an environment sourced by emacs or
  3. write out its location to somewhere where emacs can pick it up

For step 1, something like this will do:

{ stdenv, lib, fetchFromGitHub }:

stdenv.mkDerivation rec {
  pname = "emacsql-sqlite";
  version = "3.1.1";

  src = fetchFromGitHub {
    owner = "magit";
    repo = "emacsql";
    rev = version;
    hash = "sha256-b/QEpWMTyVOdkOEhPNJ0x8ukUy9Gc9gYGjnlh0WU9fY=";
  };

  sourceRoot = "source/sqlite";

  installPhase = ''
    runHook preInstall

    install -Dm555 -t $out/bin ${meta.mainProgram}

    runHook postInstall
  '';

  meta = with lib; {
    description = "Custom sqlite for emacsql";
    license = licenses.free;
    mainProgram = "emacsql-sqlite";
  };
}

For step 2, it really depends on how you normally launch emacs, but assuming you’re either running it as a systemd user service (managed by NixOS/home-manager) or a script also managed by NixOS/home-manager, you can add it to the PATH variable for the unit definition or the script.

Step 3 - decide on a global path like $XDG_CONFIG_HOME/emacs/home-manager.el or maybe /etc/emacs/nixos.el - the location doesn’t matter and whether it’s system global or user local obviously depends on your use case. And then have home-manager write out a file like this:

(setq emacsql-sqlite-executable "${lib.getExe emacsql-sqlite-binary}")

And have emacs source it:

(load "/etc/emacs/nixos.el" nil 'nomessage)
2 Likes