How to use Guile libraries in Nixpkgs

There are dozens of Guile libraries in Nixpkgs. Their recipes show that the upstream installation locations are either left nearly untouched (guile-ssh, guile-zstd), or modified like either

postPatch = ''
  substituteInPlace configure.ac \
    --replace 'SITEDIR="$datadir/guile-lib"' 'SITEDIR=$datadir/guile/site/$GUILE_EFFECTIVE_VERSION' \
    --replace 'SITECCACHEDIR="$libdir/guile-lib/guile/$GUILE_EFFECTIVE_VERSION/site-ccache"' 'SITECCACHEDIR="$libdir/guile/$GUILE_EFFECTIVE_VERSION/site-ccache"'
'';

(as in guile-lib)
or

configureFlags = [
  "--with-guile-site-dir=$(out)/${guile.siteDir}"
  "--with-guile-site-ccache-dir=$(out)/${guile.siteCcacheDir}"
];

(as in guile-xcb)
However, inside a nix shell containing such packages above, the Guile variable %load-path just evaluates to something like

("/nix/store/<hash>-guile-3.0.10/share/guile/3.0" "/nix/store/<hash>-guile-3.0.10/share/guile/site/3.0" "/nix/store/<hash>-guile-3.0.10/share/guile/site" "/nix/store/<hash>-guile-3.0.10/share/guile")

and use-modules shows that there is no code for module of these libraries.
I guess this is because Guile does not search for the “Nix site” libraries automatically, even if their locations follow the convention of Guile (in spite of being separated in a Nixy way), and (as far as I know) there’s no such thing as guile.withPackages. I wonder how can I use them without adding the paths manually to %load-path.

Solved. nix develop with mkShellNoCC just works, except that foreign library paths must be added manually to $GUILE_EXTENSIONS_PATH.

Would you be kind enough to give an example flake? I have no idea where to begin.

{
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
  };
  outputs = { self, nixpkgs, ... }@inputs :
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
      };
    in
      {
        devShells.x86_64-linux.default = pkgs.mkShellNoCC {
          buildInputs = with pkgs; [guile guile-hoot];
        };
      };
}

An example flake for future incomers!

Prefer github:NixOS/nixpkgs/nixos-unstable to avoid reliance on the registry.

Use pkgs = nixpkgs.legacyPackages.${system} instead, unless you’ve a need to configure the nixpkgs instance.

should be packages in a mkShell context.

Also, I don’t see this kind of a shell solving the issue mentioned by OP.

1 Like

One more example with GUILE_EXTENSIONS_PATH:

{
  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem
      (system:
        let
          pkgs = import nixpkgs { inherit system; };
        in
        {
          devShell = with pkgs; mkShell {
            buildInputs = [
              guile
              guile-mqtt
            ];
            shellHook = ''
              export GUILE_EXTENSIONS_PATH=$GUILE_EXTENSIONS_PATH:${pkgs.mosquitto.lib}/lib
            '';
          };
        }
      );
}
1 Like