Cannot load spatialite without specifying the full path

Hi!
I am using nix-shell --pure to create an environment containing sqlite and libspatialite.

This is how I would load it usually, after executing sqlite3: .load mod_spatialite. The module is not found. For that reason, I need to use the full path: .load /nix/store/imfyfgq1jkc25n4p77v10dndr0kjq5ki-libspatialite-5.1.0/lib/mod_spatialite.so.

I would rather not to modify my SQL scripts by adding full paths. Is there a solution for that?

Thanks for your time! :slight_smile:

I think you want buildFHSEnv from nixpkgs. This creates a script which creates an FHS sandbox: binaries are available in /bin, libraries are available in /lib and /usr/lib, etc. You can find documentation for this method in this section of the nixpkgs manual.

The following script works for me as a shell.nix/default.nix with nix-shell:

# Use whatever method you prefer to get access to nixpkgs.
{ pkgs ? import <nixpkgs> {}}:
let
  inherit (pkgs)
    buildFHSEnv;

  fhsEnv = 
    buildFHSEnv {
      name = "sqlite-with-libspatialite";
      targetPkgs = pkgs:
        builtins.attrValues {
          inherit (pkgs)
            sqlite libspatialite
          ;
        };

      # Ensure /usr/lib is part of the library search path.
      profile = ''
        export LD_LIBRARY_PATH="/usr/lib"
      '';
    };
in

fhsEnv.env

Note that this only works if I invoke it with nix-shell --pure, which isn’t an issue for you, as that’s what you’re looking for. If one were looking for a way to keep their existing environment around, one could replace the last line with fhsEnv, build the script with nix-build, and then invoke ./result/bin/sqlite-with-libspatialite to get a shell which (mostly) preserves the existing environment.

1 Like

Thank you! I used the syntax in the wiki, since it looked more reassuring to me: I am not used to nix syntax yet :slight_smile:

I then asked myself if it was possible to set LD_LIBRARY_PATH based on libspatialite, and I found a solution for that:

let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11";
  pkgs = import nixpkgs { config = {}; overlays = []; };
  lib-path = with pkgs; lib.makeLibraryPath [
    libspatialite
  ];
in

pkgs.mkShell {
  packages = with pkgs; [
    bash
    sqlite
  ];
  shellHook = ''
    export LD_LIBRARY_PATH="${lib-path}"
  '';
}

Any further feedback is welcome! :slight_smile:

Glad you found something that works for you! I may have gone overboard on avoiding with expressions; this “Best practices” section on nix.dev recommends against them, so I’ve been trying to avoid them.

My thinking in recommending buildFHSEnv is that any libraries you add to the environment would automatically show up in /usr/lib, which would minimize the updates you need to make to your nix script if you want to add more libraries in the future.

The only change to your script I might recommend is providing an explicit hash for the nixpkgs tarball you fetch. See the documentation for fetchTarball for details on this.

1 Like