Common Lisp: cffi can't find C libraries

I’m trying to use cl-gtk4, and it has 2 C dependencies: gtk4 and gobject-introspection. However when I try to load them in via a

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

  outputs = { self, nixpkgs, utils}:
    utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
      in
        {
          devShell = with pkgs; mkShell {
            nativeBuildInputs = [gtk4 gobject-introspection pkg-config];
          };
        });
}

My asd file:

(defsystem "cards-game"
  :version "0.1.0"
  :author ""
  :license ""
  :depends-on ("cards"
               "cl-gtk4")
  :components ((:module "src"
                :components
                ((:file "main"))))
  :description ""
  :in-order-to ((test-op (test-op "cards-game/tests"))))

(defsystem "cards-game/tests"
  :author ""
  :license ""
  :depends-on ("cards-game"
               "rove")
  :components ((:module "tests"
                :components
                ((:file "main"))))
  :description "Test system for cards-game"
  :perform (test-op (op c) (symbol-call :rove :run c)))

The error I get when I try to load my the asd:

  error: 
    Unable to load any of the alternatives:
       ("libgobject-2.0.so.0" "libgobject-2.0.so")
1 Like

gtk4 won’t be found by pkg-config if it is in nativeBuildInputs. nativeBuildInputs are things to be used as part of building the package (e.g. gtk4 in nativeBuildInputs be necessary if a build tool needs to be linked against that library). Our wrapper for pkg-config knows this and won’t return any build time only dependencies (unless you specifically request pkg-config to be for building build tools).

In any case in your case the library you are trying to load needs to be in buildInputs so pkg-config knows it is allowed to link against. You can read up on the details of all this in the cross compilation section of the nixpkgs manual, but you will get far with remembering that nativeBuildInputs is for this used at build time to build something for the run time later whereas buildInputs is for things that’ll be used at runtime later, mainly libraries you’ll link against.

Hm, you are just using that devShell? add the stuff to LD_LIBRARY_PATH then (CFFI will definitely look there)

1 Like

That should work, too, but from what I could tell cffi also can use pkg-config to discover libraries? That seems like it may be more robust. Not quite sure, though, as this stuff is not exactly documented.

I think you mean cffi from some other programming language. I have never seen any indication that upstream (for Common Lisp CFFI) supported pkg-config.

1 Like

As far as I can understand CFFI doesn’t support pkg-config. Also I feel like nixos should change the $LD_LIBRARY_PATH on it’s own if I’m installing a library. There may be reasons I don’t understand. Anyways I think this should be documented somewhere.

Checked again and seems like I got confused by the (build time) code in cffi that uses pkg-config to discover libffi – I kind of believed that pkg-config might be possible because OP had it in their expression.

We generally want to prevent the dynamic linker to start figuring things out on its own, since that is a potential source of impurity. Instead we always build everything in a way so that the binaries RPATH is set to include all libraries it depends on, making LD_LIBRARY_PATH unnecessary in the usual case.

Additionally, itis not really to "install a library”. In build environments we set up tool-specific search paths or pass the appropriate flags via wrappers. Setting LD_LIBRARY_PATH is potentially problematic, since it can change the behavior of binaries in the environment in a way we don’t want, so it is only done manually where necessary.

1 Like